Showing preview only (2,632K chars total). Download the full file or copy to clipboard to get everything.
Repository: Tonejs/Tone.js
Branch: dev
Commit: 03569e2a54c2
Files: 432
Total size: 2.4 MB
Directory structure:
gitextract_3dx9qg9q/
├── .github/
│ ├── CONTRIBUTING.md
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── codecov.yml
│ └── workflows/
│ ├── stale.yml
│ └── test.yml
├── .gitignore
├── CHANGELOG.md
├── LICENSE.md
├── README.md
├── Tone/
│ ├── classes.ts
│ ├── component/
│ │ ├── analysis/
│ │ │ ├── Analyser.test.ts
│ │ │ ├── Analyser.ts
│ │ │ ├── DCMeter.test.ts
│ │ │ ├── DCMeter.ts
│ │ │ ├── FFT.test.ts
│ │ │ ├── FFT.ts
│ │ │ ├── Follower.test.ts
│ │ │ ├── Follower.ts
│ │ │ ├── Meter.test.ts
│ │ │ ├── Meter.ts
│ │ │ ├── MeterBase.ts
│ │ │ ├── Waveform.test.ts
│ │ │ └── Waveform.ts
│ │ ├── channel/
│ │ │ ├── Channel.test.ts
│ │ │ ├── Channel.ts
│ │ │ ├── CrossFade.test.ts
│ │ │ ├── CrossFade.ts
│ │ │ ├── Merge.test.ts
│ │ │ ├── Merge.ts
│ │ │ ├── MidSideMerge.test.ts
│ │ │ ├── MidSideMerge.ts
│ │ │ ├── MidSideSplit.test.ts
│ │ │ ├── MidSideSplit.ts
│ │ │ ├── Mono.test.ts
│ │ │ ├── Mono.ts
│ │ │ ├── MultibandSplit.test.ts
│ │ │ ├── MultibandSplit.ts
│ │ │ ├── PanVol.test.ts
│ │ │ ├── PanVol.ts
│ │ │ ├── Panner.test.ts
│ │ │ ├── Panner.ts
│ │ │ ├── Panner3D.test.ts
│ │ │ ├── Panner3D.ts
│ │ │ ├── Recorder.test.ts
│ │ │ ├── Recorder.ts
│ │ │ ├── Solo.test.ts
│ │ │ ├── Solo.ts
│ │ │ ├── Split.test.ts
│ │ │ ├── Split.ts
│ │ │ ├── Volume.test.ts
│ │ │ └── Volume.ts
│ │ ├── dynamics/
│ │ │ ├── Compressor.test.ts
│ │ │ ├── Compressor.ts
│ │ │ ├── Gate.test.ts
│ │ │ ├── Gate.ts
│ │ │ ├── Limiter.test.ts
│ │ │ ├── Limiter.ts
│ │ │ ├── MidSideCompressor.test.ts
│ │ │ ├── MidSideCompressor.ts
│ │ │ ├── MultibandCompressor.test.ts
│ │ │ └── MultibandCompressor.ts
│ │ ├── envelope/
│ │ │ ├── AmplitudeEnvelope.test.ts
│ │ │ ├── AmplitudeEnvelope.ts
│ │ │ ├── Envelope.test.ts
│ │ │ ├── Envelope.ts
│ │ │ ├── FrequencyEnvelope.test.ts
│ │ │ └── FrequencyEnvelope.ts
│ │ ├── filter/
│ │ │ ├── BiquadFilter.test.ts
│ │ │ ├── BiquadFilter.ts
│ │ │ ├── Convolver.test.ts
│ │ │ ├── Convolver.ts
│ │ │ ├── EQ3.test.ts
│ │ │ ├── EQ3.ts
│ │ │ ├── FeedbackCombFilter.test.ts
│ │ │ ├── FeedbackCombFilter.ts
│ │ │ ├── FeedbackCombFilter.worklet.ts
│ │ │ ├── Filter.test.ts
│ │ │ ├── Filter.ts
│ │ │ ├── LowpassCombFilter.test.ts
│ │ │ ├── LowpassCombFilter.ts
│ │ │ ├── OnePoleFilter.test.ts
│ │ │ ├── OnePoleFilter.ts
│ │ │ ├── PhaseShiftAllpass.test.ts
│ │ │ └── PhaseShiftAllpass.ts
│ │ └── index.ts
│ ├── core/
│ │ ├── Global.ts
│ │ ├── Tone.ts
│ │ ├── clock/
│ │ │ ├── Clock.test.ts
│ │ │ ├── Clock.ts
│ │ │ ├── TickParam.test.ts
│ │ │ ├── TickParam.ts
│ │ │ ├── TickSignal.test.ts
│ │ │ ├── TickSignal.ts
│ │ │ ├── TickSource.test.ts
│ │ │ ├── TickSource.ts
│ │ │ ├── Ticker.test.ts
│ │ │ ├── Ticker.ts
│ │ │ ├── Transport.test.ts
│ │ │ ├── Transport.ts
│ │ │ ├── TransportEvent.test.ts
│ │ │ ├── TransportEvent.ts
│ │ │ ├── TransportRepeatEvent.test.ts
│ │ │ └── TransportRepeatEvent.ts
│ │ ├── context/
│ │ │ ├── AbstractParam.ts
│ │ │ ├── AudioContext.ts
│ │ │ ├── BaseContext.ts
│ │ │ ├── Context.test.ts
│ │ │ ├── Context.ts
│ │ │ ├── ContextInitialization.ts
│ │ │ ├── Delay.test.ts
│ │ │ ├── Delay.ts
│ │ │ ├── Destination.test.ts
│ │ │ ├── Destination.ts
│ │ │ ├── DummyContext.test.ts
│ │ │ ├── DummyContext.ts
│ │ │ ├── Gain.test.ts
│ │ │ ├── Gain.ts
│ │ │ ├── Listener.test.ts
│ │ │ ├── Listener.ts
│ │ │ ├── Offline.test.ts
│ │ │ ├── Offline.ts
│ │ │ ├── OfflineContext.test.ts
│ │ │ ├── OfflineContext.ts
│ │ │ ├── OnRunning.test.ts
│ │ │ ├── OnRunning.ts
│ │ │ ├── Param.test.ts
│ │ │ ├── Param.ts
│ │ │ ├── ToneAudioBuffer.test.ts
│ │ │ ├── ToneAudioBuffer.ts
│ │ │ ├── ToneAudioBuffers.test.ts
│ │ │ ├── ToneAudioBuffers.ts
│ │ │ ├── ToneAudioNode.test.ts
│ │ │ ├── ToneAudioNode.ts
│ │ │ ├── ToneWithContext.test.ts
│ │ │ └── ToneWithContext.ts
│ │ ├── index.ts
│ │ ├── type/
│ │ │ ├── Conversions.test.ts
│ │ │ ├── Conversions.ts
│ │ │ ├── Frequency.test.ts
│ │ │ ├── Frequency.ts
│ │ │ ├── Midi.test.ts
│ │ │ ├── Midi.ts
│ │ │ ├── NoteUnits.ts
│ │ │ ├── Ticks.test.ts
│ │ │ ├── Ticks.ts
│ │ │ ├── Time.test.ts
│ │ │ ├── Time.ts
│ │ │ ├── TimeBase.ts
│ │ │ ├── TransportTime.test.ts
│ │ │ ├── TransportTime.ts
│ │ │ └── Units.ts
│ │ ├── util/
│ │ │ ├── AdvancedTypeCheck.ts
│ │ │ ├── Debug.test.ts
│ │ │ ├── Debug.ts
│ │ │ ├── Decorator.ts
│ │ │ ├── Defaults.ts
│ │ │ ├── Draw.test.ts
│ │ │ ├── Draw.ts
│ │ │ ├── Emitter.test.ts
│ │ │ ├── Emitter.ts
│ │ │ ├── Interface.ts
│ │ │ ├── IntervalTimeline.test.ts
│ │ │ ├── IntervalTimeline.ts
│ │ │ ├── Math.ts
│ │ │ ├── StateTimeline.test.ts
│ │ │ ├── StateTimeline.ts
│ │ │ ├── Timeline.test.ts
│ │ │ ├── Timeline.ts
│ │ │ ├── TimelineValue.test.ts
│ │ │ ├── TimelineValue.ts
│ │ │ ├── TypeCheck.ts
│ │ │ └── global.d.ts
│ │ └── worklet/
│ │ ├── DelayLine.worklet.ts
│ │ ├── SingleIOProcessor.worklet.ts
│ │ ├── ToneAudioWorklet.ts
│ │ ├── ToneAudioWorkletProcessor.worklet.ts
│ │ └── WorkletGlobalScope.ts
│ ├── effect/
│ │ ├── AutoFilter.test.ts
│ │ ├── AutoFilter.ts
│ │ ├── AutoPanner.test.ts
│ │ ├── AutoPanner.ts
│ │ ├── AutoWah.test.ts
│ │ ├── AutoWah.ts
│ │ ├── BitCrusher.test.ts
│ │ ├── BitCrusher.ts
│ │ ├── BitCrusher.worklet.ts
│ │ ├── Chebyshev.test.ts
│ │ ├── Chebyshev.ts
│ │ ├── Chorus.test.ts
│ │ ├── Chorus.ts
│ │ ├── Distortion.test.ts
│ │ ├── Distortion.ts
│ │ ├── Effect.ts
│ │ ├── FeedbackDelay.test.ts
│ │ ├── FeedbackDelay.ts
│ │ ├── FeedbackEffect.ts
│ │ ├── Freeverb.test.ts
│ │ ├── Freeverb.ts
│ │ ├── FrequencyShifter.test.ts
│ │ ├── FrequencyShifter.ts
│ │ ├── JCReverb.test.ts
│ │ ├── JCReverb.ts
│ │ ├── LFOEffect.ts
│ │ ├── LFOStereoEffect.test.ts
│ │ ├── LFOStereoEffect.ts
│ │ ├── MidSideEffect.ts
│ │ ├── Phaser.test.ts
│ │ ├── Phaser.ts
│ │ ├── PingPongDelay.test.ts
│ │ ├── PingPongDelay.ts
│ │ ├── PitchShift.test.ts
│ │ ├── PitchShift.ts
│ │ ├── Reverb.test.ts
│ │ ├── Reverb.ts
│ │ ├── ReverseDelay.test.ts
│ │ ├── ReverseDelay.ts
│ │ ├── ReverseDelay.worklet.ts
│ │ ├── StereoEffect.ts
│ │ ├── StereoFeedbackEffect.ts
│ │ ├── StereoWidener.test.ts
│ │ ├── StereoWidener.ts
│ │ ├── StereoXFeedbackEffect.ts
│ │ ├── Tremolo.test.ts
│ │ ├── Tremolo.ts
│ │ ├── Vibrato.test.ts
│ │ ├── Vibrato.ts
│ │ └── index.ts
│ ├── event/
│ │ ├── Loop.test.ts
│ │ ├── Loop.ts
│ │ ├── Part.test.ts
│ │ ├── Part.ts
│ │ ├── Pattern.test.ts
│ │ ├── Pattern.ts
│ │ ├── PatternGenerator.test.ts
│ │ ├── PatternGenerator.ts
│ │ ├── Sequence.test.ts
│ │ ├── Sequence.ts
│ │ ├── ToneEvent.test.ts
│ │ ├── ToneEvent.ts
│ │ └── index.ts
│ ├── fromContext.test.ts
│ ├── fromContext.ts
│ ├── index.test.ts
│ ├── index.ts
│ ├── instrument/
│ │ ├── AMSynth.test.ts
│ │ ├── AMSynth.ts
│ │ ├── DuoSynth.test.ts
│ │ ├── DuoSynth.ts
│ │ ├── FMSynth.test.ts
│ │ ├── FMSynth.ts
│ │ ├── Instrument.ts
│ │ ├── MembraneSynth.test.ts
│ │ ├── MembraneSynth.ts
│ │ ├── MetalSynth.test.ts
│ │ ├── MetalSynth.ts
│ │ ├── ModulationSynth.ts
│ │ ├── MonoSynth.test.ts
│ │ ├── MonoSynth.ts
│ │ ├── Monophonic.ts
│ │ ├── NoiseSynth.test.ts
│ │ ├── NoiseSynth.ts
│ │ ├── PluckSynth.test.ts
│ │ ├── PluckSynth.ts
│ │ ├── PolySynth.test.ts
│ │ ├── PolySynth.ts
│ │ ├── Sampler.test.ts
│ │ ├── Sampler.ts
│ │ ├── Synth.test.ts
│ │ ├── Synth.ts
│ │ └── index.ts
│ ├── signal/
│ │ ├── Abs.test.ts
│ │ ├── Abs.ts
│ │ ├── Add.test.ts
│ │ ├── Add.ts
│ │ ├── AudioToGain.test.ts
│ │ ├── AudioToGain.ts
│ │ ├── GainToAudio.test.ts
│ │ ├── GainToAudio.ts
│ │ ├── GreaterThan.test.ts
│ │ ├── GreaterThan.ts
│ │ ├── GreaterThanZero.test.ts
│ │ ├── GreaterThanZero.ts
│ │ ├── Multiply.test.ts
│ │ ├── Multiply.ts
│ │ ├── Negate.test.ts
│ │ ├── Negate.ts
│ │ ├── Pow.test.ts
│ │ ├── Pow.ts
│ │ ├── Scale.test.ts
│ │ ├── Scale.ts
│ │ ├── ScaleExp.test.ts
│ │ ├── ScaleExp.ts
│ │ ├── Signal.test.ts
│ │ ├── Signal.ts
│ │ ├── SignalOperator.test.ts
│ │ ├── SignalOperator.ts
│ │ ├── Subtract.test.ts
│ │ ├── Subtract.ts
│ │ ├── SyncedSignal.test.ts
│ │ ├── SyncedSignal.ts
│ │ ├── ToneConstantSource.test.ts
│ │ ├── ToneConstantSource.ts
│ │ ├── WaveShaper.test.ts
│ │ ├── WaveShaper.ts
│ │ ├── Zero.test.ts
│ │ ├── Zero.ts
│ │ └── index.ts
│ └── source/
│ ├── Noise.test.ts
│ ├── Noise.ts
│ ├── OneShotSource.ts
│ ├── Source.test.ts
│ ├── Source.ts
│ ├── UserMedia.test.ts
│ ├── UserMedia.ts
│ ├── buffer/
│ │ ├── GrainPlayer.test.ts
│ │ ├── GrainPlayer.ts
│ │ ├── Player.test.ts
│ │ ├── Player.ts
│ │ ├── Players.test.ts
│ │ ├── Players.ts
│ │ ├── ToneBufferSource.test.ts
│ │ └── ToneBufferSource.ts
│ ├── index.ts
│ └── oscillator/
│ ├── AMOscillator.test.ts
│ ├── AMOscillator.ts
│ ├── FMOscillator.test.ts
│ ├── FMOscillator.ts
│ ├── FatOscillator.test.ts
│ ├── FatOscillator.ts
│ ├── LFO.test.ts
│ ├── LFO.ts
│ ├── OmniOscillator.test.ts
│ ├── OmniOscillator.ts
│ ├── Oscillator.test.ts
│ ├── Oscillator.ts
│ ├── OscillatorInterface.ts
│ ├── PWMOscillator.test.ts
│ ├── PWMOscillator.ts
│ ├── PulseOscillator.test.ts
│ ├── PulseOscillator.ts
│ ├── ToneOscillatorNode.test.ts
│ └── ToneOscillatorNode.ts
├── eslint.config.mjs
├── examples/
│ ├── README.md
│ ├── amSynth.html
│ ├── analysis.html
│ ├── animationSync.html
│ ├── bembe.html
│ ├── buses.html
│ ├── daw.html
│ ├── envelope.html
│ ├── events.html
│ ├── fmSynth.html
│ ├── funkyShape.html
│ ├── grainPlayer.html
│ ├── index.html
│ ├── js/
│ │ ├── ExampleList.json
│ │ ├── components.js
│ │ └── tone-ui.js
│ ├── jump.html
│ ├── lfoEffects.html
│ ├── meter.html
│ ├── mic.html
│ ├── mixer.html
│ ├── monoSynth.html
│ ├── noises.html
│ ├── offline.html
│ ├── oscillator.html
│ ├── pianoPhase.html
│ ├── pingPongDelay.html
│ ├── pitchShift.html
│ ├── player.html
│ ├── polySynth.html
│ ├── quantization.html
│ ├── rampTo.html
│ ├── reverb.html
│ ├── reverseDelay.html
│ ├── sampler.html
│ ├── shiny.html
│ ├── signal.html
│ ├── simpleHtml.html
│ ├── simpleSynth.html
│ ├── spatialPanner.html
│ └── stepSequencer.html
├── package.json
├── scripts/
│ ├── cspell.json
│ ├── increment_version.cjs
│ ├── tsconfig.build.json
│ ├── typedoc.json
│ └── webpack.config.cjs
├── test/
│ ├── README.md
│ ├── helper/
│ │ ├── Basic.ts
│ │ ├── CompareToFile.ts
│ │ ├── Connect.ts
│ │ ├── ConstantOutput.ts
│ │ ├── Dispose.ts
│ │ ├── EffectTests.ts
│ │ ├── InstrumentTests.ts
│ │ ├── MonophonicTests.ts
│ │ ├── Offline.ts
│ │ ├── OscillatorTests.ts
│ │ ├── OutputAudio.ts
│ │ ├── PassAudio.ts
│ │ ├── SignalTests.ts
│ │ ├── SourceTests.ts
│ │ ├── StereoSignal.ts
│ │ └── compare/
│ │ ├── Compare.ts
│ │ ├── OfflineRender.ts
│ │ ├── Plot.ts
│ │ ├── Spectrum.ts
│ │ ├── TestAudioBuffer.ts
│ │ └── index.ts
│ ├── integration/
│ │ ├── node/
│ │ │ ├── package.json
│ │ │ └── test.mjs
│ │ ├── typescript/
│ │ │ ├── package.json
│ │ │ └── test.ts
│ │ ├── unpkg/
│ │ │ ├── package.json
│ │ │ └── test.mjs
│ │ ├── vite/
│ │ │ ├── index.html
│ │ │ ├── index.ts
│ │ │ └── package.json
│ │ └── webpack/
│ │ ├── package.json
│ │ └── test.js
│ ├── scripts/
│ │ ├── test_examples.mjs
│ │ ├── test_html.mjs
│ │ ├── test_integrations.mjs
│ │ ├── test_readme.mjs
│ │ └── utils.mjs
│ └── web-test-runner.config.js
└── tsconfig.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/CONTRIBUTING.md
================================================
Bug fixes and contributions are welcome!
If you're looking for ideas for where to get started, consider jumping in on any of these areas:
### Examples
To contribute examples, please follow the current style of the examples. Add your example's title and file name to `examples/js/ExampleList.json` for it to appear in the examples list on the index page.
### Docs
There is always more work that can be done on documentation. Especially adding good examples to methods and members to make the docs more informative and useful for people coming from diverse musical and technical backgrounds.
All of the docs are written in [TypeDoc](https://typedoc.org/)-style comments in the source code. If you catch a mistake, please send a pull request.
Along with this, it'd be great to integrate more visuals and references in the docs to help illustrate concepts.
### Forum
If you are someone who is familiar with Tone.js, consider jumping in on [the forum](https://groups.google.com/forum/#!forum/tonejs) to answer some questions.
### Tutorials
I'd love to see more tutorials for newcomers to Tone.js to help them get up and running or solve a particular issue. If you make a tutorial, please send me a link.
### Tests
Tone.js has an extensive [test suite](https://github.com/Tonejs/Tone.js/wiki/Testing) using Mocha and Chai.
Along with more unit tests, it'd also be great to have more tests which run in the online context and generate music to help find bugs by ear that the automated tests might not illuminate. [Audiokit](http://audiokit.io/tests/), for example, has a great suite of aural tests.
You can also take a look at Tone.js' [code coverage](https://coveralls.io/github/Tonejs/Tone.js) to get an idea of where more tests might be helpful.
### Synths/Effects
If you'd like to contribute a cool and expressive synth or effect, I'd love to hear it. Please send me an example that I can play with along with the PR.
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Report an issue with Tone.js
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A description of what the bug is.
For help questions, check out the [forum](https://groups.google.com/forum/#!forum/tonejs).
Note: Browsers' [Autoplay Policy](https://github.com/Tonejs/Tone.js/wiki/Autoplay) leads to a lot of subtle and inconsistent bugs where Tone.js produces no sound. Check out the link for more information and the solution.
If you are experiencing loose or inaccurate timing, double check that you are [correctly scheduling events](https://github.com/Tonejs/Tone.js/wiki/Accurate-Timing).
**To Reproduce**
Please include a way to reproduce your issue. If possible, please includes a link to some example code using a platform like jsfiddle or codesandbox where the code can be edited. This makes it much easier to debug the issue and also create a validation test to verify the bug was fixed.
**Expected behavior**
A description of what you expected to happen.
**What I've tried**
How have you tried resolving/debugging this issue? This can be helpful context for getting to the heart of the issue faster and not duplicating effort.
**Additional context**
Add any other context about the problem here.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: feature request
assignees: ''
---
**The feature you'd like**
A description of a module or method which you'd like to be included in Tone.js
**Any alternatives you've considered**
Are there existing modules or methods within Tone.js which can be combined to do the same thing? Are there other libraries or reference implementations which do a similar thing?
**Additional context**
Add any other context or screenshots about the feature request here.
**Feature Requests will eventually be closed if inactive**
Consider submitted a Pull Request for the feature you want. If no one addresses your feature, it will eventually be closed due to inactivity. Though, someone could always implement your feature request after it's closed. Closing issues automatically keeps features requests from piling up.
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
1. Please make all pull requests on the `dev` branch.
2. Don't commit build files
2. Try to get all [tests](https://github.com/Tonejs/Tone.js/wiki/Testing) to pass.
================================================
FILE: .github/codecov.yml
================================================
coverage:
status:
project:
default:
target: auto
threshold: 1%
================================================
FILE: .github/workflows/stale.yml
================================================
name: "Close stale issues and PRs"
on:
schedule:
- cron: "30 1 * * *"
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
with:
any-of-labels: "cant reproduce"
stale-issue-message: "Please provide a way to reproduce the issue. Issues without a minimal (Tone.js-only) repro will be closed. A Tone.js-only repro helps ensure that the issue is not caused by another library."
days-before-close: 7
days-before-stale: 14
- uses: actions/stale@v9
with:
any-of-labels: "feature request"
stale-issue-message: "Unfortunately with limited development time, not all feature requests can be tackled. If you are interested in contributing this feature, please open a PR."
days-before-close: 30
days-before-stale: 90
================================================
FILE: .github/workflows/test.yml
================================================
name: Tests
on:
pull_request:
types: [opened, reopened, synchronize]
branches:
- dev
- main
push:
branches:
- dev
- main
jobs:
test-conventional-commit:
name: Validate PR title
runs-on: ubuntu-latest
permissions:
pull-requests: read
steps:
- uses: amannn/action-semantic-pull-request@v6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# only on PRs
if: github.event_name == 'pull_request'
run-tests:
name: All tests
permissions:
contents: read
id-token: write
runs-on: ubuntu-latest
needs: [test-conventional-commit]
env:
BROWSER: chrome
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
steps:
- name: Check out Git repository
uses: actions/checkout@v4
- name: Setup Nodejs
uses: actions/setup-node@v4
with:
node-version: 22.12.0
cache: "npm"
- name: Install dependencies
run: npm install
- name: All tests
run: npm run test
- name: Upload coverage
uses: codecov/codecov-action@v5
with:
fail_ci_if_error: false
codecov_yml_path: ./.github/codecov.yml
token: ${{ secrets.CODECOV_TOKEN }}
test-code-examples:
name: Check typedocs
permissions:
contents: read
id-token: write
runs-on: ubuntu-latest
needs: [test-conventional-commit]
steps:
- name: Check out Git repository
uses: actions/checkout@v4
- name: Setup Nodejs
uses: actions/setup-node@v4
with:
node-version: 22.12.0
cache: "npm"
- name: Install dependencies
run: npm install
- name: Build Docs
run: npm run build && npm run docs:json
- name: tsdoc @example checks
run: npm run test:examples
test-html-examples:
name: Run HTML Examples
permissions:
contents: read
id-token: write
runs-on: ubuntu-latest
needs: [test-conventional-commit]
steps:
- name: Check out Git repository
uses: actions/checkout@v4
- name: Setup Nodejs
uses: actions/setup-node@v4
with:
node-version: 22.12.0
cache: "npm"
- name: Install dependencies
run: npm install
- name: Build
run: npm run build
- name: Code example tests
run: npm run test:html
test-lint:
name: Linting and environment checks
permissions:
contents: read
id-token: write
runs-on: ubuntu-latest
needs: [test-conventional-commit]
steps:
- name: Check out Git repository
uses: actions/checkout@v4
- name: Setup Nodejs
uses: actions/setup-node@v4
with:
node-version: 22.12.0
cache: "npm"
- name: Install dependencies
run: npm install
- name: Linting
run: npm run lint
- name: Spell check
run: npm run spellcheck
test-readme:
name: Ensure that examples in the README compile
permissions:
contents: read
id-token: write
runs-on: ubuntu-latest
needs: [test-conventional-commit]
steps:
- name: Check out Git repository
uses: actions/checkout@v4
- name: Setup Nodejs
uses: actions/setup-node@v4
with:
node-version: 22.12.0
cache: "npm"
- name: Install dependencies
run: npm install
- name: Build
run: npm run build
- name: Test
run: npm run test:readme
test-integrations:
name: Test integrations
permissions:
contents: read
id-token: write
runs-on: ubuntu-latest
needs: [test-conventional-commit]
steps:
- name: Check out Git repository
uses: actions/checkout@v4
- name: Setup Nodejs
uses: actions/setup-node@v4
with:
node-version: 22.12.0
cache: "npm"
- name: Install dependencies
run: npm install
- name: Build
run: npm run build
- name: Test
run: npm run test:integrations
publish:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
# make sure all the tests pass first
needs:
[
run-tests,
test-code-examples,
test-html-examples,
test-lint,
test-readme,
test-integrations,
]
# not on PRs
if: github.event_name != 'pull_request'
env:
GITHUB_CI: true
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v6
with:
node-version: 24
registry-url: "https://registry.npmjs.org"
# Need to unset this in order to use OICD
- name: Unset NODE_AUTH_TOKEN
run: unset NODE_AUTH_TOKEN
- name: Install dependencies
run: npm install
- name: Build
run: npm run build
- name: Increment version
run: npm run increment
- name: Publish @next
# dev branch gets published with @next tag
run: npm publish --tag next --provenance --access public
if: ${{ github.ref == 'refs/heads/dev' }}
- name: Publish @latest
# main branch gets published with @latest tag
run: npm publish --provenance --access public
if: ${{ github.ref == 'refs/heads/main' }}
================================================
FILE: .gitignore
================================================
.DS_Store
*.asd
*.scssc
*.sublime-workspace
*.sublime-project
node_modules
TODO.txt
wiki
examples/scratch.html
examples/deps/FileSaver.js
examples/oscilloscope.html
examples/graph.html
test/performance
test/mainTest.js
test/Main.js
test/supports.html
coverage/
build/*
**/dist/*
examples/scratch.js
examples/scratch.ts
Tone/version.js
Tone/version.ts
Tone/index.js
test/test.js
docs
.vscode
tone.d.ts
examples/scratch.ts
test/integration/*/package-lock.json
================================================
FILE: CHANGELOG.md
================================================
# 15.0.x
- `set` in constructor even if AudioBuffer is not from std-audio-context ([0399687](https://github.com/Tonejs/Tone.js/commit/0399687)), closes [#991](https://github.com/Tonejs/Tone.js/issues/991)
- ability to mute a sequence ([ac856bc](https://github.com/Tonejs/Tone.js/commit/ac856bc)), closes [#823](https://github.com/Tonejs/Tone.js/issues/823)
- Add `"type": "module"` to `package.json` ([69055ba](https://github.com/Tonejs/Tone.js/commit/69055ba))
- Add back `main` as ESM build ([8cc6e8a](https://github.com/Tonejs/Tone.js/commit/8cc6e8a))
- Add Pattern.index ([205c438](https://github.com/Tonejs/Tone.js/commit/205c438))
- Add test for duplicate events ([d5c8a25](https://github.com/Tonejs/Tone.js/commit/d5c8a25))
- adding @category definitions for docs, fixing some typos/mistakes along the way ([0e2b5b9](https://github.com/Tonejs/Tone.js/commit/0e2b5b9))
- adding createMediaElementSource ([301f8cd](https://github.com/Tonejs/Tone.js/commit/301f8cd)), closes [#756](https://github.com/Tonejs/Tone.js/issues/756)
- Allow instrument and PolySynth to be scheduled to the transport stop/loop events ([954a4fc](https://github.com/Tonejs/Tone.js/commit/954a4fc)), closes [#924](https://github.com/Tonejs/Tone.js/issues/924)
- allow worklet-based effects to be used with native contexts (#1131) ([f06ff17](https://github.com/Tonejs/Tone.js/commit/f06ff17)), closes [#1131](https://github.com/Tonejs/Tone.js/issues/1131)
- Analyser constructor smoothing option bug fix ([afb5284](https://github.com/Tonejs/Tone.js/commit/afb5284))
- bumping standardized-audio-context version ([cbdb596](https://github.com/Tonejs/Tone.js/commit/cbdb596))
- Chebyshev order must be an integer ([4f9aece](https://github.com/Tonejs/Tone.js/commit/4f9aece)), closes [#844](https://github.com/Tonejs/Tone.js/issues/844)
- correctly offset phase for each oscillator ([0ac1da5](https://github.com/Tonejs/Tone.js/commit/0ac1da5)), closes [#733](https://github.com/Tonejs/Tone.js/issues/733)
- custom decay curve #1107 ([d463286](https://github.com/Tonejs/Tone.js/commit/d463286)), closes [#1107](https://github.com/Tonejs/Tone.js/issues/1107)
- Don't reschedule source when offset is very small ([444d617](https://github.com/Tonejs/Tone.js/commit/444d617)), closes [#999](https://github.com/Tonejs/Tone.js/issues/999) [#944](https://github.com/Tonejs/Tone.js/issues/944)
- Export remaining effect option interfaces (#1293) ([2b8039b](https://github.com/Tonejs/Tone.js/commit/2b8039b)), closes [#1293](https://github.com/Tonejs/Tone.js/issues/1293)
- exporting Mono ([8b996bc](https://github.com/Tonejs/Tone.js/commit/8b996bc)), closes [#765](https://github.com/Tonejs/Tone.js/issues/765)
- fix the wrong variable name 'event' in Emitter.ts ([46bd717](https://github.com/Tonejs/Tone.js/commit/46bd717))
- Garbage collect nodes used for Transport syncing ([a392067](https://github.com/Tonejs/Tone.js/commit/a392067))
- increasing attack/release above 0 to avoid distortion ([b39883e](https://github.com/Tonejs/Tone.js/commit/b39883e)), closes [#770](https://github.com/Tonejs/Tone.js/issues/770)
- latest std-audio-context ([8915e1b](https://github.com/Tonejs/Tone.js/commit/8915e1b)), closes [#720](https://github.com/Tonejs/Tone.js/issues/720)
- Less verbose unit types (#1181) ([9353d33](https://github.com/Tonejs/Tone.js/commit/9353d33)), closes [#1181](https://github.com/Tonejs/Tone.js/issues/1181)
- Load only a single AudioWorklet ([75a802c](https://github.com/Tonejs/Tone.js/commit/75a802c))
- Memoize getTicksAtTime and getSecondsAtTime ([da73385](https://github.com/Tonejs/Tone.js/commit/da73385))
- Parse note strings with three sharps or flats. ([5cd3560](https://github.com/Tonejs/Tone.js/commit/5cd3560))
- pass in partials to LFO ([fdc7eb4](https://github.com/Tonejs/Tone.js/commit/fdc7eb4)), closes [#814](https://github.com/Tonejs/Tone.js/issues/814)
- polysynth does not reschedule event if disposed ([e3a611f](https://github.com/Tonejs/Tone.js/commit/e3a611f))
- Recorder resumes if start() is called in paused state (#1266) ([ead4f21](https://github.com/Tonejs/Tone.js/commit/ead4f21)), closes [#1266](https://github.com/Tonejs/Tone.js/issues/1266)
- remove implicit "stop" scheduling ([0b7a352](https://github.com/Tonejs/Tone.js/commit/0b7a352)), closes [#778](https://github.com/Tonejs/Tone.js/issues/778)
- Reverb input string time (#1313) ([bf3ee91](https://github.com/Tonejs/Tone.js/commit/bf3ee91)), closes [#1313](https://github.com/Tonejs/Tone.js/issues/1313) [#1253](https://github.com/Tonejs/Tone.js/issues/1253)
- Reverse Emitter off callback loop for correct removal of duplicate events ([b5f582e](https://github.com/Tonejs/Tone.js/commit/b5f582e))
- Revert "fix for AudioBufferSourceNode stop time miscalculation" ([e1c6631](https://github.com/Tonejs/Tone.js/commit/e1c6631))
- Smooth RMS values per channel in Meter ([45d2009](https://github.com/Tonejs/Tone.js/commit/45d2009)), closes [#882](https://github.com/Tonejs/Tone.js/issues/882)
- throws error when polysynth is used with a non monophonic class ([4f5353e](https://github.com/Tonejs/Tone.js/commit/4f5353e)), closes [#939](https://github.com/Tonejs/Tone.js/issues/939)
- use now() instead of currentTime ([9e9b3d2](https://github.com/Tonejs/Tone.js/commit/9e9b3d2))
- Use reciprocal of tempo when syncing time signals to Transport ([64c8a29](https://github.com/Tonejs/Tone.js/commit/64c8a29)), closes [#879](https://github.com/Tonejs/Tone.js/issues/879)
- Using web-test-runner for tests, updating import paths (#1242) ([aaf880c](https://github.com/Tonejs/Tone.js/commit/aaf880c)), closes [#1242](https://github.com/Tonejs/Tone.js/issues/1242)
- warn if event is scheduled without using the scheduled time. ([6dd22e7](https://github.com/Tonejs/Tone.js/commit/6dd22e7)), closes [#959](https://github.com/Tonejs/Tone.js/issues/959)
- fix: load base64 encoded sounds when baseUrl is not empty ([a771811](https://github.com/Tonejs/Tone.js/commit/a771811)), closes [#898](https://github.com/Tonejs/Tone.js/issues/898)
- fix: loading non relative URLs ([f7bdff0](https://github.com/Tonejs/Tone.js/commit/f7bdff0))
- feat: sub-tick scheduling ([33e14d0](https://github.com/Tonejs/Tone.js/commit/33e14d0))
### BREAKING CHANGES
- Deprecating singleton variables, use singleton getter instead (#1233) ([3d42017](https://github.com/Tonejs/Tone.js/commit/3d42017)), closes [#1233](https://github.com/Tonejs/Tone.js/issues/1233)
- Removing double-encoding of urls (#1254) ([de086f5](https://github.com/Tonejs/Tone.js/commit/de086f5)), closes [#1254](https://github.com/Tonejs/Tone.js/issues/1254)
# 14.7.x
### Features
- **Converted to typescript!!!**
- adding AudioWorkletNode constructors to Context ([f7bdd75](https://github.com/Tonejs/Tone.js/commit/f7bdd75))
- adding ability to get the frequency at the FFT index ([22cecdc](https://github.com/Tonejs/Tone.js/commit/22cecdc281c8076c054affaef9dc422665acda2e))
- adding AudioWorkletNode constructors to Context ([f7bdd75](https://github.com/Tonejs/Tone.js/commit/f7bdd7528fa9549740dc514df6308303c060e091))
- adding BiquadFilter ([75617d3](https://github.com/Tonejs/Tone.js/commit/75617d341fe44ca5d332ea4e547f07c266a54753)), closes [#686](https://github.com/Tonejs/Tone.js/issues/686)
- adding linting to jsdocs ([10ef513](https://github.com/Tonejs/Tone.js/commit/10ef513))
- adding send/receive to Channel ([703f27a](https://github.com/Tonejs/Tone.js/commit/703f27a))
- Adding triggerRelease to PluckSynth ([04405af](https://github.com/Tonejs/Tone.js/commit/04405af))
- Can set the parameter after constructing Param ([23ca0f9](https://github.com/Tonejs/Tone.js/commit/23ca0f9))
- adding onerror to Sampler ([7236600](https://github.com/Tonejs/Tone.js/commit/7236600182d336d6598f86d7d7afe8761e733774)), closes [#605](https://github.com/Tonejs/Tone.js/issues/605)
- Chorus extends StereoFeedbackEffect ([a28f1af](https://github.com/Tonejs/Tone.js/commit/a28f1af)), closes [#575](https://github.com/Tonejs/Tone.js/issues/575)
- Convolver is just a wrapper around the ConvolverNode, no longer an effect ([1668dec](https://github.com/Tonejs/Tone.js/commit/1668dec))
- Get an oscillator wave as an array ([9ad519e](https://github.com/Tonejs/Tone.js/commit/9ad519e))
- OfflineContext returns a ToneAudioBuffer ([889dafa](https://github.com/Tonejs/Tone.js/commit/889dafa))
- OfflineContext yields thread every second of audio rendered ([1154470](https://github.com/Tonejs/Tone.js/commit/1154470)), closes [#436](https://github.com/Tonejs/Tone.js/issues/436)
- Renaming TransportTimelineSignal to SyncedSignal ([86853fb](https://github.com/Tonejs/Tone.js/commit/86853fb))
- es6 output ([e5d28ba](https://github.com/Tonejs/Tone.js/commit/e5d28baa5f02c19a6f1c8c50c99e98bd1551d15b))
- Render a segment of the envelope as an array ([fc5b6f7](https://github.com/Tonejs/Tone.js/commit/fc5b6f7))
- testing examples in jsdocs ([e306319](https://github.com/Tonejs/Tone.js/commit/e306319))
- Wrapper around the AudioWorkletNode ([2ee8cb1](https://github.com/Tonejs/Tone.js/commit/2ee8cb1))
- Input/Outputs are no longer arrays.
- simplifies connect/disconnect logic greatly. Simplifies API to just have clearly named inputs/outputs instead of overloading input/output connect numbers
- Using "Destination" instead of "Master" for output
- More consistent with Web Audio API
- FrequencyShifter - thanks @Foaly
- PolySynth does not require a polyphony value.
- Voice allocation and disposing is done automatically based on demand.
- MetalSynth and MembraneSynth extends Monophonic enabling them to be used in PolySynth
- OnePoleFilter is a 6b-per-octave lowpass or highpass filter
- Using OnePoleFilter in PluckSynth and LowpassCombFilter
- latencyHint is now set in constructor ([ba8e82b](https://github.com/Tonejs/Tone.js/commit/ba8e82b1ca8a841a23d6e774641916019c37cc92)), closes [#658](https://github.com/Tonejs/Tone.js/issues/658)
- meter output can be normalRange in addition to decibels ([2625a13](https://github.com/Tonejs/Tone.js/commit/2625a134b62af117c1c525a4e631e4e52b25ba90))
- option to pass in the number of input channels to Panner ([d966735](https://github.com/Tonejs/Tone.js/commit/d966735bd97bddc70039bce5a48f26413054eddc)), closes [#609](https://github.com/Tonejs/Tone.js/issues/609)
### BREAKING CHANGES
- TransportTimelineSignal renamed SyncedSignal
- Master renamed Destination
- Buffer renamed ToneAudioBuffer
- Buffer.on("loaded") is should now use: `Tone.loaded(): Promise<void>`
- Removing bower ([71c8b3b](https://github.com/Tonejs/Tone.js/commit/71c8b3bbb96e45cfc4aa2cce8a2d8c61a092c91e)), closes [#197](https://github.com/Tonejs/Tone.js/issues/197)
- Removing Ctrl classes ([51d06bd](https://github.com/Tonejs/Tone.js/commit/51d06bd9873b2f1936a3169930f9696f1ccfb845))
- `Players.get(name: string)` is renamed to `Players.player(name: string)`
# 13.8.25
- Moving to common.js-style code
### BREAKING CHANGES
- AudioNode.prototype.connect is no longer overwritten. This means that you can no longer connect native nodes to Tone.js Nodes.
- Tone.connect(srcNode, destNode, [ouputNum], [inputNum]) is the way to connect native Web Audio nodes with Tone.js nodes.
# 13.4.9
- Updating semantic versioning to be more in line with other [semvers](https://semver.org/). Now version is 13.x.x
- logging full version
- Added Object notation for Tone.TimeBase and classes that extend it.
- i.e. Tone.Time({'4n' : 1, '8t' : 2})
- Replacement for deprecated expression strings.
- Tone.Meter uses RMS instead of peak (thanks [@Idicious](https://github.com/Idicious))
- Tone.Sampler supports polyphonic syntax (thanks [@zfan40](https://github.com/zfan40))
- Building files with [webpack](https://webpack.js.org/)
- Follower/Gate uses a single "smoothing" value instead of separate attacks and releases
- Changing references to `window` allowing it to not throw error in node context
- Testing examples
- Tone.Channel combines Tone.PanVol with Tone.Solo.
- Removing require.html example.
- adding `partialCount` and `baseType` to Oscillator classes, helps with getting/setting complex types.
# r12
- Consolidating all shims into [shim folder](https://github.com/Tonejs/Tone.js/tree/dev/Tone/shim)
- Using ConstantSourceNode in Signal when available
- switching to eslint from jshint
- Running [CI tests](https://travis-ci.org/Tonejs/Tone.js/) on Firefox, Chrome (latest and canary) and Safari (latest and version 9).
- [Tone.Reverb](https://tonejs.github.io/docs/Reverb) is a convolution-based stereo reverb. [Example](https://tonejs.github.io/examples/#reverb).
- Optimizing basic Oscillator types and many Signal use-case
- Optimizing basic connection use-case of Tone.Signal where one signal is controlling another signal
- Testing rendered output against an existing audio file for continuity and consistency
- Optimizing triggerAttack/Release by starting/stopping oscillators when not playing
- [TickSource](https://tonejs.github.io/docs/TickSource) (used in Clock and Player) tracks the elapsed ticks
- Improved precision of tracking ticks in Transport and Clock
- `Player.position` returns the playback position of the AudioBuffer accounting for any playbackRate changes
- Removing `retrigger` option with Tone.Player. Tone.BufferSource should be used if retriggering is desired.
**BREAKING CHANGES:**
- Tone.TimeBase and all classes that extend it not longer support string expressions.
RATIONALE :
_ Since all classes implement `valueOf`, expressions can be composed in JS instead of as strings
_ e.g. `Time('4n') * 2 + Time('3t')` instead of `Time('4n * 2 + 3t')` \* this change greatly simplifies the code and is more performant
# r11
- [Code coverage](https://coveralls.io/github/Tonejs/Tone.js) analysis
- [Dev build](https://tonejs.github.io/build/dev/Tone.js) with each successful commit
- [Versioned docs](https://tonejs.github.io/docs/Tone) plus a [dev build of the docs](https://tonejs.github.io/docs/dev/Tone) on successful commits
- [Tone.AudioNode](https://tonejs.github.io/docs/AudioNode) is base class for all classes which generate or process audio
- [Tone.Sampler](https://tonejs.github.io/docs/Sampler) simplifies creating multisampled instruments
- [Tone.Solo](https://tonejs.github.io/docs/Solo) makes it easier to mute/solo audio
- [Mixer](https://tonejs.github.io/examples/#mixer) and [sampler](https://tonejs.github.io/examples/#sampler) examples
- Making type-checking methods static
- [Tone.TransportTimelineSignal](https://tonejs.github.io/docs/TransportTimelineSignal) is a signal which can be scheduled along the Transport
- [Tone.FFT](https://tonejs.github.io/docs/FFT) and [Tone.Waveform](https://tonejs.github.io/docs/Waveform) abstract Tone.Analyser
- [Tone.Meter](https://tonejs.github.io/docs/Meter) returns decibels
- [Tone.Envelope](https://tonejs.github.io/docs/Envelope) uses exponential approach instead of exponential curve for decay and release curves
- [Tone.BufferSource](https://tonejs.github.io/docs/BufferSource) fadeIn/Out can be either "linear" or "exponential" curve
# r10
- Tone.Context wraps AudioContext
- Tone.OfflineContext wraps OfflineAudioContext
- Tone.Offline: method for rendering audio offline
- Rewriting tests with Tone.Offline
- Optimizing Tone.Draw to only loop when events are scheduled: [#194](https://github.com/Tonejs/Tone.js/issues/194)
- Time.eval->valueOf which takes advantage of build-in primitive evaluation [#205](https://github.com/Tonejs/Tone.js/issues/205)
- [Offline example](https://tonejs.github.io/examples/#offline)
# r9
- Tone.Clock performance and lookAhead updates.
- Tone.Transport.lookAhead = seconds|'playback'|'interactive'|'balanced'
- Convolver.load and Player.load returns Promise
- Tone.ExternalInput -> Tone.UserMedia, simplified API, open() returns Promise.
- Tone.Draw for animation-frame synced drawing
- Compressor Parameters are now Tone.Params
- Bug fixes
# r8
- Transport.seconds returns the progress in seconds.
- Buffer.from/toArray, Float32Array <-> Buffer conversions
- Buffer.slice(start, end) slices and returns a subsection of the Buffer
- Source.sync now syncs all subsequent calls to `start` and `stop` to the TransportTime instead of the AudioContext time.
- e.g. source.sync().start(0).stop(0.8); //plays source between 0 and 0.8 of the Transport
- Transport.on("start" / "stop") callbacks are invoked just before the event.
- Param can accept an LFO description in the constructor or .value
- e.g. param.value = {min : 10, max : 20, frequency : 0.4}
- Time.TimeBase has clone/copy methods.
- Tone.Buffer.prototype.load returns Promise
- Using Tone.Delay and Tone.Gain everywhere
- Patch for Chrome 53+ issue of not correctly scheduling AudioParams with setValueAtTime
- Panner3D and Tone.Listener wrap native PannerNode and AudioListener to give 3D panning ability.
# r7
- MetalSynth creates metallic, cymbal sounds
- DrumSynth -> MembraneSynth
- FMOscillator, AMOscillator types
- FatOscillator creates multiple oscillators and detunes them slightly
- FM, AM, Fat Oscillators incorporated into OmniOscillator
- Simplified FM and AM Synths and APIs
- Panner.pan is between -1,1 like the StereoPannerNode
- Pruned away unused (or little used) Signal classes.
- All this functionality will be available when the AudioWorkerNode is introduced.
- Clock uses Web Workers instead of requestAnimationFrame which allows it to run in the background.
- Removed `startMobile`. Using [StartAudioContext](https://github.com/tambien/StartAudioContext) in examples.
- Automated test runner using [Travis CI](https://travis-ci.org/Tonejs/Tone.js/)
- Simplified NoiseSynth by removing filter and filter envelope.
- Added new timing primitive types: Time, Frequency, TransportTime.
- Switching parameter position of type and size in Tone.Analyser
- Tone.Meter uses Tone.Analyser instead of ScriptProcessorNode.
- Tone.Envelope has 5 new attack/release curves: "sine", "cosine", "bounce", "ripple", "step"
- Renamed Tone.SimpleSynth -> Tone.Synth
- Tone.Buffers combines multiple buffers
- Tone.BufferSource a low-level wrapper, and Tone.MultiPlayer which is good for multisampled instruments.
- Tone.GrainPlayer: granular synthesis buffer player.
- Simplified Sampler
DEPRECATED:
- Removed SimpleFM and SimpleAM
# r6
- Added PitchShift and Vibrato Effect.
- Added Timeline/TimelineState/TimelineSignal which keeps track of all scheduled state changes.
- Clock uses requestAnimationFrame instead of ScriptProcessorNode
- Removed `onended` event from Tone.Source
- Refactored tests into individual files.
- Renamed some Signal methods: `exponentialRampToValueNow`->`exponentialRampToValue`, `setCurrentValueNow`->`setRampPoint`
- LFO no longer starts at bottom of cycle. Starts at whatever phase it's set at.
- Transport is an event emitter. triggers events on "start", "stop", "pause", and "loop".
- Oscillator accepts a "partials" array.
- Microphone inherits from ExternalInput which is generalized for different inputs.
- New scheduling methods on Transport - `schedule`, `scheduleOnce`, and `scheduleRepeat`.
- Tone.Gain and Tone.Delay classes wrap the native Web Audio nodes.
- Moved [MidiToScore](https://github.com/Tonejs/MidiConvert) and [TypeScript](https://github.com/Tonejs/TypeScript) definitions to separate repos.
- Tone.Param wraps the native AudioParam and allows for unit conversion.
- Quantization with Transport.quantize and using "@" in any Time. [Read more](https://github.com/Tonejs/Tone.js/wiki/Time).
- Control-rate generators for value interpolation, patterns, random numbers, and markov chains.
- schedulable musical events: Tone.Event, Tone.Loop, Tone.Part, Tone.Pattern, Tone.Sequence.
- Player's playbackRate is now a signal and Noise includes a playbackRate signal.
- All filterEnvelopes use new Tone.FrequencyEnvelope with frequency units and `baseFrequency` and `octaves` instead of `min` and `max`.
- Phaser uses "octaves" instead of "depth" to be more consistent across the whole Tone.js API.
- Presets now have [their own repo](https://github.com/Tonejs/Presets)
DEPRECATED:
- `setTimeout`, `setInterval`, `setTimeline` in favor of new `schedule`, `scheduleOnce`, and `scheduleRepeat`.
- Tone.Signal no longer takes an AudioParam in the first argument. Use Tone.Param instead.
- Tone.Buffer.onload/onprogress/onerror is deprecated. Use `Tone.Buffer.on("load", callback)` instead.
# r5
- reverse buffer for Player and Sampler.
- Tone.Volume for simple volume control in Decibels.
- Panner uses StereoPannerNode when available.
- AutoFilter and Tremolo effects.
- Made many attributes read-only. preventing this common type of error: `oscillator.frequency = 200` when it should be `oscillator.frequency.value = 200`.
- Envelope supports "linear" and "exponential" attack curves.
- Renamed Tone.EQ -> Tone.EQ3.
- Tone.DrumSynth makes kick and tom sounds.
- Tone.MidSideCompressor and Tone.MidSideSplit/Tone.MidSideMerge
- Tone.Oscillator - can specify the number of partials in the type: i.e. "sine10", "triangle3", "square4", etc.
- mute/unmute the master output: `Tone.Master.mute = true`.
- 3 new simplified synths: SimpleSynth, SimpleAM and SimpleFM
- `harmonicity` is a signal-rate value for all instruments.
- expose Q in Phaser.
- unit conversions using Tone.Type for signals and LFO.
- [new docs](http://tonejs.org/docs)
- [updated examples](http://tonejs.org/examples)
# r4
- `toFrequency` accepts notes by name (i.e. `"C4"`)
- Envelope no longer accepts exponential scaling, only Tone.ScaledEnvelope
- Buffer progress and load events which tracks the progress of all downloads
- Buffer only accepts a single url
- Sampler accepts multiple samples as an object.
- `setPitch` in sampler -> `setNote`
- Deprecated MultiSampler - use Sampler with PolySynth instead
- Added [cdn](http://cdn.tonejs.org/latest/Tone.min.js) - please don't use for production code
- Renamed DryWet to CrossFade
- Functions return `this` to allow for chaining. i.e. `player.toMaster().start(2)`.
- Added `units` to Signal class which allows signals to be set in terms of Tone.Time, Tone.Frequency, Numbers, or Decibels.
- Replaced set/get method with ES5 dot notation. i.e. `player.setVolume(-10)` is now `player.volume.value = -10`.
To ramp the volume use either `player.volume.linearRampToValueNow(-10, "4n")`, or the new `rampTo` method which automatically selects the ramp (linear|exponential) based on the type of data.
- set/get methods for all components
- syncSignal and unsyncSignal moved from Signal to Transport
- Add/Multiply/Subtract/Min/Max/GreaterThan/LessThan all extend Tone.Signal which allows them to be scheduled and automated just like Tone.Signal.
- Deprecated Tone.Divide and Tone.Inverse. They were more complicated than they were useful.
BREAKING CHANGES:
The API has been changed consistently to use `.attribute` for getting and setting instead of `getAttribute` and `setAttribute` methods. The reasoning for this is twofold: firstly, Tone.Signal attributes were previously limited in their scheduling capabilities when set through a setter function. For exactly, it was not possible to do a setValueAtTime on the `bpm` of the Transport. Secondly, the new EcmaScript 5 getter/setter approach resembles the Web Audio API much more closely, which will make intermixing the two APIs even easier.
If you're using Sublime Text, one way to transition from the old API to the new one is with a regex find/replace:
find `Tone.Transport.setBpm\((\d+)\)` and replace it with `Tone.Transport.bpm.value = $1`.
Or if setBpm was being invoked with a rampTime:
find `Tone.Transport.setBpm\((\d+)\, (\d+)\)` and replace it with `Tone.Transport.bpm.rampTo($1, $2)`.
# r3
Core Change:
- Swing parameter on Transport
- Player loop positions stay in tempo-relative terms even with tempo changes
- Envelope ASDR stay in tempo-relative terms even with tempo changes
- Modified build script to accommodate using requirejs with build and minified version
Signal Processing:
- Tone.Expr: signal processing expression parser for Tone.Signal math
- All signal binary operators accept two signals as inputs
- Deprecated Tone.Threshold - new class Tone.GreaterThanZero
- NOT, OR, AND, and IfThenElse signal logic operators
- Additional signal classes: Inverse, Divide, Pow, AudioToGain, Subtract
- Scale no longer accepts input min/max. Assumes [0,1] range.
- Normalize class if scaling needs to happen from other input ranges
- WaveShaper function wraps the WaveShaperNode
Effects:
- Distortion and Chebyshev distortion effects
- Compressor and MultibandCompressor
- MidSide effect type and StereoWidener
- Convolver effect and example
Synths:
- Setters on PluckSynth and PulseOscillator
- new PWMOscillator
- OmniOscillator which combines PWMOscillator, Oscillator, and PulseOscillator into one
- NoiseSynth
# r2
- PluckSynth - Karplus-Strong Plucked String modeling synth
- Freeverb
- John Chowning Reverb (JCReverb)
- LowpassCombFilter and FeedbackCombFilter
- Sampler with pitch control
- Clock tick callback is out of the audio thread using setTimeout
- Optimized Tone.Modulo
- Tests run using OfflineRenderingContext
- Fixed Transport bug where timeouts/intervals and timelines were on a different tick counter
- AmplitudeEnvelope + triggerAttackDecay on Envelope
- Instruments inherit from Tone.Instrument base-class
- midi<-->note conversions
# r1 - First!
================================================
FILE: LICENSE.md
================================================
MIT License
Copyright (c) 2014-2025 Yotam Mann
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# Tone.js
[](https://codecov.io/gh/Tonejs/Tone.js)
Tone.js is a Web Audio framework for creating interactive music in the browser. The architecture of Tone.js aims to be familiar to both musicians and audio programmers creating web-based audio applications. On the high-level, Tone offers common DAW (digital audio workstation) features like a global transport for synchronizing and scheduling events as well as prebuilt synths and effects. Additionally, Tone provides high-performance building blocks to create your own synthesizers, effects, and complex control signals.
- [API](https://tonejs.github.io/docs/)
- [Examples](https://tonejs.github.io/examples/)
# Installation
There are two ways to incorporate Tone.js into a project. First, it can be installed locally into a project using `npm`:
```bash
npm install tone // Install the latest stable version
npm install tone@next // Or, alternatively, use the 'next' version
```
Add Tone.js to a project using the JavaScript `import` syntax:
```js
import * as Tone from "tone";
```
Tone.js is also hosted at unpkg.com. It can be added directly within an HTML document, as long as it precedes any project scripts. [See the example here](https://github.com/Tonejs/Tone.js/blob/master/examples/simpleHtml.html) for more details.
```html
<script src="http://unpkg.com/tone"></script>
```
# Hello Tone
```javascript
//create a synth and connect it to the main output (your speakers)
const synth = new Tone.Synth().toDestination();
//play a middle 'C' for the duration of an 8th note
synth.triggerAttackRelease("C4", "8n");
```
## Tone.Synth
`Tone.Synth` is a basic synthesizer with a single oscillator and an ADSR envelope.
### triggerAttack / triggerRelease
`triggerAttack` starts the note (the amplitude is rising), and `triggerRelease` is when the amplitude is going back to 0 (i.e. **note off**).
```javascript
const synth = new Tone.Synth().toDestination();
const now = Tone.now();
// trigger the attack immediately
synth.triggerAttack("C4", now);
// wait one second before triggering the release
synth.triggerRelease(now + 1);
```
### triggerAttackRelease
`triggerAttackRelease` is a combination of `triggerAttack` and `triggerRelease`
The first argument to the note which can either be a frequency in hertz (like `440`) or as "pitch-octave" notation (like `"D#2"`).
The second argument is the duration that the note is held. This value can either be in seconds, or as a [tempo-relative value](https://github.com/Tonejs/Tone.js/wiki/Time).
The third (optional) argument of `triggerAttackRelease` is _when_ along the AudioContext time the note should play. It can be used to schedule events in the future.
```javascript
const synth = new Tone.Synth().toDestination();
const now = Tone.now();
synth.triggerAttackRelease("C4", "8n", now);
synth.triggerAttackRelease("E4", "8n", now + 0.5);
synth.triggerAttackRelease("G4", "8n", now + 1);
```
## Time
Web Audio has advanced, sample accurate scheduling capabilities. The AudioContext time is what the Web Audio API uses to schedule events, starts at 0 when the page loads and counts up in **seconds**.
`Tone.now()` gets the current time of the AudioContext.
```javascript
setInterval(() => console.log(Tone.now()), 100);
```
Tone.js abstracts away the AudioContext time. Instead of defining all values in seconds, any method which takes time as an argument can accept a number or a string. For example `"4n"` is a quarter-note, `"8t"` is an eighth-note triplet, and `"1m"` is one measure.
[Read about Time encodings](https://github.com/Tonejs/Tone.js/wiki/Time).
# Starting Audio
**IMPORTANT**: Browsers will not play _any_ audio until a user clicks something (like a play button). Run your Tone.js code only after calling `Tone.start()` from a event listener which is triggered by a user action such as "click" or "keydown".
`Tone.start()` returns a promise, the audio will be ready only after that promise is resolved. Scheduling or playing audio before the AudioContext is running will result in silence or incorrect scheduling.
```javascript
//attach a click listener to a play button
document.querySelector("button")?.addEventListener("click", async () => {
await Tone.start();
console.log("audio is ready");
});
```
# Scheduling
## Transport
`Tone.getTransport()` returns the main timekeeper. Unlike the AudioContext clock, it can be started, stopped, looped and adjusted on the fly. You can think of it like the arrangement view in a Digital Audio Workstation.
Multiple events and parts can be arranged and synchronized along the Transport. `Tone.Loop` is a simple way to create a looped callback that can be scheduled to start and stop.
```javascript
// create two monophonic synths
const synthA = new Tone.FMSynth().toDestination();
const synthB = new Tone.AMSynth().toDestination();
//play a note every quarter-note
const loopA = new Tone.Loop((time) => {
synthA.triggerAttackRelease("C2", "8n", time);
}, "4n").start(0);
//play another note every off quarter-note, by starting it "8n"
const loopB = new Tone.Loop((time) => {
synthB.triggerAttackRelease("C4", "8n", time);
}, "4n").start("8n");
// all loops start when the Transport is started
Tone.getTransport().start();
// ramp up to 800 bpm over 10 seconds
Tone.getTransport().bpm.rampTo(800, 10);
```
Since Javascript callbacks are **not precisely timed**, the sample-accurate time of the event is passed into the callback function. **Use this time value to schedule the events**.
# Instruments
There are numerous synths to choose from including `Tone.FMSynth`, `Tone.AMSynth` and `Tone.NoiseSynth`.
All of these instruments are **monophonic** (single voice) which means that they can only play one note at a time.
To create a **polyphonic** synthesizer, use `Tone.PolySynth`, which accepts a monophonic synth as its first parameter and automatically handles the note allocation so you can pass in multiple notes. The API is similar to the monophonic synths, except `triggerRelease` must be given a note or array of notes.
```javascript
const synth = new Tone.PolySynth(Tone.Synth).toDestination();
const now = Tone.now();
synth.triggerAttack("D4", now);
synth.triggerAttack("F4", now + 0.5);
synth.triggerAttack("A4", now + 1);
synth.triggerAttack("C5", now + 1.5);
synth.triggerAttack("E5", now + 2);
synth.triggerRelease(["D4", "F4", "A4", "C5", "E5"], now + 4);
```
# Samples
Sound generation is not limited to synthesized sounds. You can also load a sample and play that back in a number of ways. `Tone.Player` is one way to load and play back an audio file.
```javascript
const player = new Tone.Player(
"https://tonejs.github.io/audio/berklee/gong_1.mp3"
).toDestination();
Tone.loaded().then(() => {
player.start();
});
```
`Tone.loaded()` returns a promise which resolves when _all_ audio files are loaded. It's a helpful shorthand instead of waiting on each individual audio buffer's `onload` event to resolve.
## Tone.Sampler
Multiple samples can also be combined into an instrument. If you have audio files organized by note, `Tone.Sampler` will pitch shift the samples to fill in gaps between notes. So for example, if you only have every 3rd note on a piano sampled, you could turn that into a full piano sample.
Unlike the other synths, Tone.Sampler is polyphonic so doesn't need to be passed into Tone.PolySynth
```javascript
const sampler = new Tone.Sampler({
urls: {
C4: "C4.mp3",
"D#4": "Ds4.mp3",
"F#4": "Fs4.mp3",
A4: "A4.mp3",
},
release: 1,
baseUrl: "https://tonejs.github.io/audio/salamander/",
}).toDestination();
Tone.loaded().then(() => {
sampler.triggerAttackRelease(["Eb4", "G4", "Bb4"], 4);
});
```
# Effects
In the above examples, the sources were always connected directly to the `Destination`, but the output of the synth could also be routed through one (or more) effects before going to the speakers.
```javascript
const player = new Tone.Player({
url: "https://tonejs.github.io/audio/berklee/gurgling_theremin_1.mp3",
loop: true,
autostart: true,
});
//create a distortion effect
const distortion = new Tone.Distortion(0.4).toDestination();
//connect a player to the distortion
player.connect(distortion);
```
The connection routing is flexible, connections can run serially or in parallel.
```javascript
const player = new Tone.Player({
url: "https://tonejs.github.io/audio/drum-samples/loops/ominous.mp3",
autostart: true,
});
const filter = new Tone.Filter(400, "lowpass").toDestination();
const feedbackDelay = new Tone.FeedbackDelay(0.125, 0.5).toDestination();
// connect the player to the feedback delay and filter in parallel
player.connect(filter);
player.connect(feedbackDelay);
```
Multiple nodes can be connected to the same input enabling sources to share effects. `Tone.Gain` is useful utility node for creating complex routing.
# Signals
Like the underlying Web Audio API, Tone.js is built with audio-rate signal control over nearly everything. This is a powerful feature which allows for sample-accurate synchronization and scheduling of parameters.
`Signal` properties have a few built in methods for creating automation curves.
For example, the `frequency` parameter on `Oscillator` is a Signal so you can create a smooth ramp from one frequency to another.
```javascript
const osc = new Tone.Oscillator().toDestination();
// start at "C4"
osc.frequency.value = "C4";
// ramp to "C2" over 2 seconds
osc.frequency.rampTo("C2", 2);
// start the oscillator for 2 seconds
osc.start().stop("+3");
```
# AudioContext
Tone.js creates an AudioContext when it loads and shims it for maximum browser compatibility using [standardized-audio-context](https://github.com/chrisguttandin/standardized-audio-context). The AudioContext can be accessed at `Tone.getContext`. Or set your own AudioContext using `Tone.setContext(audioContext)`.
# MIDI
To use MIDI files, you'll first need to convert them into a JSON format which Tone.js can understand using [Midi](https://tonejs.github.io/Midi/).
# Performance
Tone.js makes extensive use of the native Web Audio Nodes such as the GainNode and WaveShaperNode for all signal processing, which enables Tone.js to work well on both desktop and mobile browsers.
[This wiki](https://github.com/Tonejs/Tone.js/wiki/Performance) article has some suggestions related to performance for best practices.
# Testing
Tone.js runs an extensive test suite using [mocha](https://mochajs.org/) and [chai](http://chaijs.com/) with nearly 100% coverage. Passing builds on the 'dev' branch are published on npm as `tone@next`.
# Contributing
There are many ways to contribute to Tone.js. Check out [this wiki](https://github.com/Tonejs/Tone.js/wiki/Contributing) if you're interested.
# References and Inspiration
- [Many of Chris Wilson's Repositories](https://github.com/cwilso)
- [Many of Mohayonao's Repositories](https://github.com/mohayonao)
- [The Spec](http://webaudio.github.io/web-audio-api/)
- [Sound on Sound - Synth Secrets](http://www.soundonsound.com/sos/may99/articles/synthsec.htm)
- [Miller Puckette - Theory and Techniques of Electronic Music](http://msp.ucsd.edu/techniques.htm)
- [standardized-audio-context](https://github.com/chrisguttandin/standardized-audio-context)
================================================
FILE: Tone/classes.ts
================================================
export * from "./component/index.js";
export * from "./core/index.js";
export * from "./effect/index.js";
export * from "./event/index.js";
export * from "./instrument/index.js";
export * from "./signal/index.js";
export * from "./source/index.js";
================================================
FILE: Tone/component/analysis/Analyser.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { Noise } from "../../source/Noise.js";
import { Analyser } from "./Analyser.js";
describe("Analyser", () => {
BasicTests(Analyser);
it("can get and set properties", () => {
const anl = new Analyser();
anl.set({
size: 32,
smoothing: 0.2,
});
const values = anl.get();
expect(values.size).to.equal(32);
expect(values.smoothing).to.equal(0.2);
anl.dispose();
});
it("can correctly set the size", () => {
const anl = new Analyser("fft", 512);
expect(anl.size).to.equal(512);
anl.size = 1024;
expect(anl.size).to.equal(1024);
anl.dispose();
});
it("can run fft analysis", () => {
const anl = new Analyser("fft", 512);
const analysis = anl.getValue();
expect(analysis.length).to.equal(512);
analysis.forEach((val) => {
expect(val).is.lessThan(0);
});
anl.dispose();
});
it("can run waveform analysis", (done) => {
const noise = new Noise();
const anl = new Analyser("waveform", 256);
noise.connect(anl);
noise.start();
setTimeout(() => {
const analysis = anl.getValue();
expect(analysis.length).to.equal(256);
analysis.forEach((val) => {
expect(val).is.within(-1, 1);
});
anl.dispose();
noise.dispose();
done();
}, 300);
});
it("throws an error if an invalid type is set", () => {
const anl = new Analyser("fft", 512);
expect(() => {
// @ts-ignore
anl.type = "invalid";
}).to.throw(Error);
anl.dispose();
});
it("can do multichannel analysis", () => {
const anl = new Analyser({
type: "waveform",
channels: 2,
size: 512,
});
expect(anl.getValue().length).to.equal(2);
expect((anl.getValue()[0] as Float32Array).length).to.equal(512);
anl.dispose();
});
});
================================================
FILE: Tone/component/analysis/Analyser.ts
================================================
import { Gain } from "../../core/context/Gain.js";
import {
InputNode,
OutputNode,
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { NormalRange, PowerOfTwo } from "../../core/type/Units.js";
import { assert, assertRange } from "../../core/util/Debug.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { Split } from "../channel/Split.js";
export type AnalyserType = "fft" | "waveform";
export interface AnalyserOptions extends ToneAudioNodeOptions {
size: PowerOfTwo;
type: AnalyserType;
smoothing: NormalRange;
channels: number;
}
/**
* Wrapper around the native Web Audio's [AnalyserNode](http://webaudio.github.io/web-audio-api/#idl-def-AnalyserNode).
* Extracts FFT or Waveform data from the incoming signal.
* @category Component
*/
export class Analyser extends ToneAudioNode<AnalyserOptions> {
readonly name: string = "Analyser";
readonly input: InputNode;
readonly output: OutputNode;
/**
* The analyser node.
*/
private _analyzers: AnalyserNode[] = [];
/**
* Input and output are a gain node
*/
private _gain: Gain;
/**
* The channel splitter node
*/
private _split: Split;
/**
* The analysis type
*/
private _type!: AnalyserType;
/**
* The buffer that the FFT data is written to
*/
private _buffers: Float32Array[] = [];
/**
* @param type The return type of the analysis, either "fft", or "waveform".
* @param size The size of the FFT. This must be a power of two in the range 16 to 16384.
*/
constructor(type?: AnalyserType, size?: number);
constructor(options?: Partial<AnalyserOptions>);
constructor() {
const options = optionsFromArguments(
Analyser.getDefaults(),
arguments,
["type", "size"]
);
super(options);
this.input =
this.output =
this._gain =
new Gain({ context: this.context });
this._split = new Split({
context: this.context,
channels: options.channels,
});
this.input.connect(this._split);
assertRange(options.channels, 1);
// create the analyzers
for (let channel = 0; channel < options.channels; channel++) {
this._analyzers[channel] = this.context.createAnalyser();
this._split.connect(this._analyzers[channel], channel, 0);
}
// set the values initially
this.size = options.size;
this.type = options.type;
this.smoothing = options.smoothing;
}
static getDefaults(): AnalyserOptions {
return Object.assign(ToneAudioNode.getDefaults(), {
size: 1024,
smoothing: 0.8,
type: "fft" as AnalyserType,
channels: 1,
});
}
/**
* Run the analysis given the current settings. If {@link channels} = 1,
* it will return a Float32Array. If {@link channels} > 1, it will
* return an array of Float32Arrays where each index in the array
* represents the analysis done on a channel.
*/
getValue(): Float32Array | Float32Array[] {
this._analyzers.forEach((analyser, index) => {
const buffer = this._buffers[index];
if (this._type === "fft") {
analyser.getFloatFrequencyData(buffer);
} else if (this._type === "waveform") {
analyser.getFloatTimeDomainData(buffer);
}
});
if (this.channels === 1) {
return this._buffers[0];
} else {
return this._buffers;
}
}
/**
* The size of analysis. This must be a power of two in the range 16 to 16384.
*/
get size(): PowerOfTwo {
return this._analyzers[0].frequencyBinCount;
}
set size(size: PowerOfTwo) {
this._analyzers.forEach((analyser, index) => {
analyser.fftSize = size * 2;
this._buffers[index] = new Float32Array(size);
});
}
/**
* The number of channels the analyser does the analysis on. Channel
* separation is done using {@link Split}
*/
get channels(): number {
return this._analyzers.length;
}
/**
* The analysis function returned by analyser.getValue(), either "fft" or "waveform".
*/
get type(): AnalyserType {
return this._type;
}
set type(type: AnalyserType) {
assert(
type === "waveform" || type === "fft",
`Analyser: invalid type: ${type}`
);
this._type = type;
}
/**
* 0 represents no time averaging with the last analysis frame.
*/
get smoothing(): NormalRange {
return this._analyzers[0].smoothingTimeConstant;
}
set smoothing(val: NormalRange) {
this._analyzers.forEach((a) => (a.smoothingTimeConstant = val));
}
/**
* Clean up.
*/
dispose(): this {
super.dispose();
this._analyzers.forEach((a) => a.disconnect());
this._split.dispose();
this._gain.dispose();
return this;
}
}
================================================
FILE: Tone/component/analysis/DCMeter.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { PassAudio } from "../../../test/helper/PassAudio.js";
import { Signal } from "../../signal/Signal.js";
import { DCMeter } from "./DCMeter.js";
describe("DCMeter", () => {
BasicTests(DCMeter);
context("DCMetering", () => {
it("passes the audio through", () => {
return PassAudio((input) => {
const meter = new DCMeter().toDestination();
input.connect(meter);
});
});
it("can get the rms level of the incoming signal", (done) => {
const meter = new DCMeter();
const osc = new Signal(2).connect(meter);
setTimeout(() => {
expect(meter.getValue()).to.be.closeTo(2, 0.1);
meter.dispose();
osc.dispose();
done();
}, 400);
});
});
});
================================================
FILE: Tone/component/analysis/DCMeter.ts
================================================
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { MeterBase, MeterBaseOptions } from "./MeterBase.js";
export type DCMeterOptions = MeterBaseOptions;
/**
* DCMeter gets the raw value of the input signal at the current time.
* @see {@link Meter}.
*
* @example
* const meter = new Tone.DCMeter();
* const mic = new Tone.UserMedia();
* mic.open();
* // connect mic to the meter
* mic.connect(meter);
* // the current level of the mic
* const level = meter.getValue();
* @category Component
*/
export class DCMeter extends MeterBase<DCMeterOptions> {
readonly name: string = "DCMeter";
constructor(options?: Partial<DCMeterOptions>);
constructor() {
super(optionsFromArguments(DCMeter.getDefaults(), arguments));
this._analyser.type = "waveform";
this._analyser.size = 256;
}
/**
* Get the signal value of the incoming signal
*/
getValue(): number {
const value = this._analyser.getValue() as Float32Array;
return value[0];
}
}
================================================
FILE: Tone/component/analysis/FFT.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { Noise } from "../../source/Noise.js";
import { FFT } from "./FFT.js";
describe("FFT", () => {
BasicTests(FFT);
it("can get and set properties", () => {
const fft = new FFT();
fft.set({
size: 128,
smoothing: 0.4,
});
const values = fft.get();
expect(values.size).to.equal(128);
expect(values.smoothing).to.equal(0.4);
fft.dispose();
});
it("can correctly set the size", () => {
const fft = new FFT(512);
expect(fft.size).to.equal(512);
fft.size = 1024;
expect(fft.size).to.equal(1024);
fft.dispose();
});
it("can set the smoothing", () => {
const fft = new FFT(512);
fft.smoothing = 0.2;
expect(fft.smoothing).to.equal(0.2);
fft.dispose();
});
it("can get the frequency values of each index of the return array", () => {
const fft = new FFT(32);
expect(fft.getFrequencyOfIndex(0)).to.be.closeTo(0, 1);
expect(fft.getFrequencyOfIndex(16)).to.be.closeTo(
fft.context.sampleRate / 4,
1
);
fft.dispose();
});
it("can run waveform analysis", (done) => {
const noise = new Noise();
const fft = new FFT(256);
noise.connect(fft);
noise.start();
setTimeout(() => {
const analysis = fft.getValue();
expect(analysis.length).to.equal(256);
analysis.forEach((value) => {
expect(value).is.within(-Infinity, 0);
});
fft.dispose();
noise.dispose();
done();
}, 300);
});
it("outputs a normal range", (done) => {
const noise = new Noise();
const fft = new FFT({
normalRange: true,
});
noise.connect(fft);
noise.start();
setTimeout(() => {
const analysis = fft.getValue();
analysis.forEach((value) => {
expect(value).is.within(0, 1);
});
fft.dispose();
noise.dispose();
done();
}, 300);
});
});
================================================
FILE: Tone/component/analysis/FFT.ts
================================================
import { ToneAudioNode } from "../../core/context/ToneAudioNode.js";
import { dbToGain } from "../../core/type/Conversions.js";
import { Hertz, NormalRange, PowerOfTwo } from "../../core/type/Units.js";
import { assert } from "../../core/util/Debug.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { MeterBase, MeterBaseOptions } from "./MeterBase.js";
export interface FFTOptions extends MeterBaseOptions {
size: PowerOfTwo;
smoothing: NormalRange;
normalRange: boolean;
}
/**
* Get the current frequency data of the connected audio source using a fast Fourier transform.
* Read more about FFT algorithms on [Wikipedia] (https://en.wikipedia.org/wiki/Fast_Fourier_transform).
* @category Component
*/
export class FFT extends MeterBase<FFTOptions> {
readonly name: string = "FFT";
/**
* If the output should be in decibels or normal range between 0-1. If `normalRange` is false,
* the output range will be the measured decibel value, otherwise the decibel value will be converted to
* the range of 0-1
*/
normalRange: boolean;
/**
* @param size The size of the FFT. Value must be a power of two in the range 16 to 16384.
*/
constructor(size?: PowerOfTwo);
constructor(options?: Partial<FFTOptions>);
constructor() {
const options = optionsFromArguments(FFT.getDefaults(), arguments, [
"size",
]);
super(options);
this.normalRange = options.normalRange;
this._analyser.type = "fft";
this.size = options.size;
}
static getDefaults(): FFTOptions {
return Object.assign(ToneAudioNode.getDefaults(), {
normalRange: false,
size: 1024,
smoothing: 0.8,
});
}
/**
* Gets the current frequency data from the connected audio source.
* Returns the frequency data of length {@link size} as a Float32Array of decibel values.
*/
getValue(): Float32Array {
const values = this._analyser.getValue() as Float32Array;
return values.map((v) => (this.normalRange ? dbToGain(v) : v));
}
/**
* The size of analysis. This must be a power of two in the range 16 to 16384.
* Determines the size of the array returned by {@link getValue} (i.e. the number of
* frequency bins). Large FFT sizes may be costly to compute.
*/
get size(): PowerOfTwo {
return this._analyser.size;
}
set size(size) {
this._analyser.size = size;
}
/**
* 0 represents no time averaging with the last analysis frame.
*/
get smoothing(): NormalRange {
return this._analyser.smoothing;
}
set smoothing(val) {
this._analyser.smoothing = val;
}
/**
* Returns the frequency value in hertz of each of the indices of the FFT's {@link getValue} response.
* @example
* const fft = new Tone.FFT(32);
* console.log([0, 1, 2, 3, 4].map(index => fft.getFrequencyOfIndex(index)));
*/
getFrequencyOfIndex(index: number): Hertz {
assert(
0 <= index && index < this.size,
`index must be greater than or equal to 0 and less than ${this.size}`
);
return (index * this.context.sampleRate) / (this.size * 2);
}
}
================================================
FILE: Tone/component/analysis/Follower.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { Offline } from "../../../test/helper/Offline.js";
import { PassAudio } from "../../../test/helper/PassAudio.js";
import { Signal } from "../../signal/Signal.js";
import { Follower } from "./Follower.js";
describe("Follower", () => {
BasicTests(Follower);
context("Envelope Following", () => {
it("handles getter/setter as Object", () => {
const foll = new Follower();
const values = {
smoothing: 0.2,
};
foll.set(values);
expect(foll.get()).to.have.keys(["smoothing"]);
expect(foll.get().smoothing).to.be.closeTo(0.2, 0.001);
foll.dispose();
});
it("can be constructed with an object", () => {
const follower = new Follower({
smoothing: 0.5,
});
expect(follower.smoothing).to.be.closeTo(0.5, 0.001);
follower.dispose();
});
it("smooths the incoming signal at 0.1", async () => {
const buffer = await Offline(() => {
const foll = new Follower(0.1).toDestination();
const sig = new Signal(0);
sig.connect(foll);
sig.setValueAtTime(1, 0.1);
sig.setValueAtTime(0, 0.3);
}, 0.41);
expect(buffer.getValueAtTime(0)).to.be.closeTo(0, 0.01);
expect(buffer.getValueAtTime(0.1)).to.be.closeTo(0.0, 0.01);
expect(buffer.getValueAtTime(0.15)).to.be.closeTo(0.95, 0.05);
expect(buffer.getValueAtTime(0.2)).to.be.closeTo(1, 0.01);
expect(buffer.getValueAtTime(0.3)).to.be.closeTo(1, 0.01);
expect(buffer.getValueAtTime(0.35)).to.be.closeTo(0.05, 0.05);
expect(buffer.getValueAtTime(0.4)).to.be.closeTo(0, 0.01);
});
it("smooths the incoming signal at 0.05", async () => {
const buffer = await Offline(() => {
const foll = new Follower(0.05).toDestination();
const sig = new Signal(0);
sig.connect(foll);
sig.setValueAtTime(1, 0.1);
sig.setValueAtTime(0, 0.3);
}, 0.41);
expect(buffer.getValueAtTime(0)).to.be.closeTo(0, 0.01);
expect(buffer.getValueAtTime(0.1)).to.be.closeTo(0.0, 0.01);
expect(buffer.getValueAtTime(0.125)).to.be.closeTo(0.95, 0.05);
expect(buffer.getValueAtTime(0.15)).to.be.closeTo(1, 0.01);
expect(buffer.getValueAtTime(0.3)).to.be.closeTo(1, 0.01);
expect(buffer.getValueAtTime(0.325)).to.be.closeTo(0.05, 0.05);
expect(buffer.getValueAtTime(0.35)).to.be.closeTo(0, 0.01);
});
it("smooths the incoming signal at 0.2", async () => {
const buffer = await Offline(() => {
const foll = new Follower(0.2).toDestination();
const sig = new Signal(0);
sig.connect(foll);
sig.setValueAtTime(1, 0.1);
sig.setValueAtTime(0, 0.3);
}, 0.51);
expect(buffer.getValueAtTime(0)).to.be.closeTo(0, 0.01);
expect(buffer.getValueAtTime(0.1)).to.be.closeTo(0.0, 0.01);
expect(buffer.getValueAtTime(0.2)).to.be.closeTo(0.95, 0.05);
expect(buffer.getValueAtTime(0.3)).to.be.closeTo(1, 0.01);
expect(buffer.getValueAtTime(0.4)).to.be.closeTo(0.05, 0.05);
expect(buffer.getValueAtTime(0.5)).to.be.closeTo(0, 0.01);
});
it("smooths the incoming signal at 0.5", async () => {
const buffer = await Offline(() => {
const foll = new Follower(0.5).toDestination();
const sig = new Signal(0);
sig.connect(foll);
sig.setValueAtTime(1, 0.1);
sig.setValueAtTime(0, 0.6);
}, 1.11);
expect(buffer.getValueAtTime(0)).to.be.closeTo(0, 0.01);
expect(buffer.getValueAtTime(0.1)).to.be.closeTo(0.0, 0.01);
expect(buffer.getValueAtTime(0.35)).to.be.closeTo(0.95, 0.05);
expect(buffer.getValueAtTime(0.6)).to.be.closeTo(1, 0.01);
expect(buffer.getValueAtTime(0.85)).to.be.closeTo(0.05, 0.05);
expect(buffer.getValueAtTime(1.1)).to.be.closeTo(0, 0.01);
});
it("passes the incoming signal through", () => {
return PassAudio((input) => {
const follower = new Follower().toDestination();
input.connect(follower);
});
});
});
});
================================================
FILE: Tone/component/analysis/Follower.ts
================================================
import {
InputNode,
OutputNode,
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { Time } from "../../core/type/Units.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { Abs } from "../../signal/Abs.js";
import { OnePoleFilter } from "../filter/OnePoleFilter.js";
export interface FollowerOptions extends ToneAudioNodeOptions {
smoothing: Time;
}
/**
* Follower is a simple envelope follower.
* It's implemented by applying a lowpass filter to the absolute value of the incoming signal.
* ```
* +-----+ +---------------+
* Input +--> Abs +----> OnePoleFilter +--> Output
* +-----+ +---------------+
* ```
* @category Component
*/
export class Follower extends ToneAudioNode<FollowerOptions> {
readonly name: string = "Follower";
readonly input: InputNode;
readonly output: OutputNode;
/**
* Private reference to the smoothing parameter
*/
private _smoothing: Time;
/**
* The lowpass filter
*/
private _lowpass: OnePoleFilter;
/**
* The absolute value
*/
private _abs: Abs;
/**
* @param smoothing The rate of change of the follower.
*/
constructor(smoothing?: Time);
constructor(options?: Partial<FollowerOptions>);
constructor() {
const options = optionsFromArguments(
Follower.getDefaults(),
arguments,
["smoothing"]
);
super(options);
this._abs = this.input = new Abs({ context: this.context });
this._lowpass = this.output = new OnePoleFilter({
context: this.context,
frequency: 1 / this.toSeconds(options.smoothing),
type: "lowpass",
});
this._abs.connect(this._lowpass);
this._smoothing = options.smoothing;
}
static getDefaults(): FollowerOptions {
return Object.assign(ToneAudioNode.getDefaults(), {
smoothing: 0.05,
});
}
/**
* The amount of time it takes a value change to arrive at the updated value.
*/
get smoothing(): Time {
return this._smoothing;
}
set smoothing(smoothing) {
this._smoothing = smoothing;
this._lowpass.frequency = 1 / this.toSeconds(this.smoothing);
}
dispose(): this {
super.dispose();
this._abs.dispose();
this._lowpass.dispose();
return this;
}
}
================================================
FILE: Tone/component/analysis/Meter.test.ts
================================================
import { expect } from "chai";
import { BasicTests, warns } from "../../../test/helper/Basic.js";
import { PassAudio } from "../../../test/helper/PassAudio.js";
import { Oscillator } from "../../source/oscillator/Oscillator.js";
import { Merge } from "../channel/Merge.js";
import { Meter } from "./Meter.js";
describe("Meter", () => {
BasicTests(Meter);
context("Metering", () => {
it("handles getter/setter as Object", () => {
const meter = new Meter();
const values = {
smoothing: 0.2,
};
meter.set(values);
expect(meter.get().smoothing).to.equal(0.2);
meter.dispose();
});
it("can be constructed with the smoothing", () => {
const meter = new Meter(0.5);
expect(meter.smoothing).to.equal(0.5);
meter.dispose();
});
it("returns an array of channels if channels > 1", () => {
const meter = new Meter({
channelCount: 4,
});
expect((meter.getValue() as number[]).length).to.equal(4);
meter.dispose();
});
it("can be constructed with an object", () => {
const meter = new Meter({
smoothing: 0.3,
});
expect(meter.smoothing).to.equal(0.3);
meter.dispose();
});
it("passes the audio through", () => {
return PassAudio((input) => {
const meter = new Meter().toDestination();
input.connect(meter);
});
});
it("warns of deprecated method", () => {
warns(() => {
const meter = new Meter().toDestination();
meter.getLevel();
meter.dispose();
});
});
it("can get the rms level of the incoming signal", (done) => {
const meter = new Meter();
const osc = new Oscillator().connect(meter).start();
osc.volume.value = -6;
setTimeout(() => {
expect(meter.getValue()).to.be.closeTo(-9, 1);
meter.dispose();
osc.dispose();
done();
}, 400);
});
it("returns 0 below a threshold", (done) => {
const meter = new Meter({
normalRange: true,
});
const osc = new Oscillator().connect(meter).start();
osc.volume.value = -101;
setTimeout(() => {
expect(meter.getValue()).to.equal(0);
meter.dispose();
osc.dispose();
done();
}, 400);
});
it("can get the values in normal range", (done) => {
const meter = new Meter({
normalRange: true,
});
const osc = new Oscillator().connect(meter).start();
osc.volume.value = -6;
setTimeout(() => {
expect(meter.getValue()).to.be.closeTo(0.35, 0.15);
meter.dispose();
osc.dispose();
done();
}, 400);
});
it("can get the rms levels for multiple channels", (done) => {
const meter = new Meter({
channelCount: 2,
smoothing: 0.5,
});
const merge = new Merge().connect(meter);
const osc0 = new Oscillator().connect(merge, 0, 0).start();
const osc1 = new Oscillator().connect(merge, 0, 1).start();
osc0.volume.value = -6;
osc1.volume.value = -18;
setTimeout(() => {
const values = meter.getValue();
expect(values).to.have.lengthOf(2);
expect(values[0]).to.be.closeTo(-9, 1);
expect(values[1]).to.be.closeTo(-21, 1);
meter.dispose();
merge.dispose();
osc0.dispose();
osc1.dispose();
done();
}, 400);
});
});
});
================================================
FILE: Tone/component/analysis/Meter.ts
================================================
import { dbToGain, gainToDb } from "../../core/type/Conversions.js";
import { NormalRange } from "../../core/type/Units.js";
import { warn } from "../../core/util/Debug.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { Analyser } from "./Analyser.js";
import { MeterBase, MeterBaseOptions } from "./MeterBase.js";
export interface MeterOptions extends MeterBaseOptions {
smoothing: NormalRange;
normalRange: boolean;
channelCount: number;
}
/**
* Meter gets the [RMS](https://en.wikipedia.org/wiki/Root_mean_square)
* of an input signal. It can also get the raw value of the input signal.
* Setting `normalRange` to `true` will covert the output to a range of
* 0-1. See an example using a graphical display
* [here](https://tonejs.github.io/examples/meter).
* @see {@link DCMeter}.
*
* @example
* const meter = new Tone.Meter();
* const mic = new Tone.UserMedia();
* mic.open();
* // connect mic to the meter
* mic.connect(meter);
* // the current level of the mic
* setInterval(() => console.log(meter.getValue()), 100);
* @category Component
*/
export class Meter extends MeterBase<MeterOptions> {
readonly name: string = "Meter";
/**
* If the output should be in decibels or normal range between 0-1. If `normalRange` is false,
* the output range will be the measured decibel value, otherwise the decibel value will be converted to
* the range of 0-1
*/
normalRange: boolean;
/**
* A value from between 0 and 1 where 0 represents no time averaging with the last analysis frame.
*/
smoothing: number;
/**
* The previous frame's value for each channel.
*/
private _rms: number[];
/**
* @param smoothing The amount of smoothing applied between frames.
*/
constructor(smoothing?: NormalRange);
constructor(options?: Partial<MeterOptions>);
constructor() {
const options = optionsFromArguments(Meter.getDefaults(), arguments, [
"smoothing",
]);
super(options);
this.input =
this.output =
this._analyser =
new Analyser({
context: this.context,
size: 256,
type: "waveform",
channels: options.channelCount,
});
this.smoothing = options.smoothing;
this.normalRange = options.normalRange;
this._rms = new Array(options.channelCount);
this._rms.fill(0);
}
static getDefaults(): MeterOptions {
return Object.assign(MeterBase.getDefaults(), {
smoothing: 0.8,
normalRange: false,
channelCount: 1,
});
}
/**
* Use {@link getValue} instead. For the previous getValue behavior, use DCMeter.
* @deprecated
*/
getLevel(): number | number[] {
warn("'getLevel' has been changed to 'getValue'");
return this.getValue();
}
/**
* Below this threshold, stop smoothing.
*/
private minValue = dbToGain(-100);
/**
* Get the current value of the incoming signal.
* Output is in decibels when {@link normalRange} is `false`.
* If {@link channels} = 1, then the output is a single number
* representing the value of the input signal. When {@link channels} > 1,
* then each channel is returned as a value in a number array.
*/
getValue(): number | number[] {
const aValues = this._analyser.getValue();
const channelValues =
this.channels === 1
? [aValues as Float32Array]
: (aValues as Float32Array[]);
const vals = channelValues.map((values, channel) => {
const totalSquared = values.reduce(
(total, current) => total + current * current,
0
);
const rms = Math.sqrt(totalSquared / values.length);
if (rms < this.minValue) {
this._rms[channel] = 0;
} else {
// the rms can only fall at the rate of the smoothing
// but can jump up instantly
this._rms[channel] = Math.max(
rms,
this._rms[channel] * this.smoothing
);
}
return this.normalRange
? this._rms[channel]
: gainToDb(this._rms[channel]);
});
if (this.channels === 1) {
return vals[0];
} else {
return vals;
}
}
/**
* The number of channels of analysis.
*/
get channels(): number {
return this._analyser.channels;
}
dispose(): this {
super.dispose();
this._analyser.dispose();
return this;
}
}
================================================
FILE: Tone/component/analysis/MeterBase.ts
================================================
import {
InputNode,
OutputNode,
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { Analyser } from "./Analyser.js";
export type MeterBaseOptions = ToneAudioNodeOptions;
/**
* The base class for Metering classes.
*/
export class MeterBase<
Options extends MeterBaseOptions,
> extends ToneAudioNode<Options> {
readonly name: string = "MeterBase";
/**
* The signal to be analyzed
*/
input: InputNode;
/**
* The output is just a pass through of the input
*/
output: OutputNode;
/**
* The analyser node for the incoming signal
*/
protected _analyser: Analyser;
constructor(options?: Partial<MeterBaseOptions>);
constructor() {
super(optionsFromArguments(MeterBase.getDefaults(), arguments));
this.input =
this.output =
this._analyser =
new Analyser({
context: this.context,
size: 256,
type: "waveform",
});
}
dispose(): this {
super.dispose();
this._analyser.dispose();
return this;
}
}
================================================
FILE: Tone/component/analysis/Waveform.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { Noise } from "../../source/Noise.js";
import { Waveform } from "./Waveform.js";
describe("Waveform", () => {
BasicTests(Waveform);
it("can get and set properties", () => {
const anl = new Waveform();
anl.set({
size: 128,
});
const values = anl.get();
expect(values.size).to.equal(128);
anl.dispose();
});
it("can correctly set the size", () => {
const anl = new Waveform(512);
expect(anl.size).to.equal(512);
anl.size = 1024;
expect(anl.size).to.equal(1024);
anl.dispose();
});
it("can run waveform analysis", (done) => {
const noise = new Noise();
const anl = new Waveform(256);
noise.connect(anl);
noise.start();
setTimeout(() => {
const analysis = anl.getValue();
expect(analysis.length).to.equal(256);
analysis.forEach((value) => {
expect(value).is.within(-1, 1);
});
anl.dispose();
noise.dispose();
done();
}, 300);
});
});
================================================
FILE: Tone/component/analysis/Waveform.ts
================================================
import { PowerOfTwo } from "../../core/type/Units.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { MeterBase, MeterBaseOptions } from "./MeterBase.js";
export interface WaveformOptions extends MeterBaseOptions {
/**
* The size of the Waveform. Value must be a power of two in the range 16 to 16384.
*/
size: PowerOfTwo;
}
/**
* Get the current waveform data of the connected audio source.
* @category Component
*/
export class Waveform extends MeterBase<WaveformOptions> {
readonly name: string = "Waveform";
/**
* @param size The size of the Waveform. Value must be a power of two in the range 16 to 16384.
*/
constructor(size?: PowerOfTwo);
constructor(options?: Partial<WaveformOptions>);
constructor() {
const options = optionsFromArguments(
Waveform.getDefaults(),
arguments,
["size"]
);
super(options);
this._analyser.type = "waveform";
this.size = options.size;
}
static getDefaults(): WaveformOptions {
return Object.assign(MeterBase.getDefaults(), {
size: 1024,
});
}
/**
* Return the waveform for the current time as a Float32Array where each value in the array
* represents a sample in the waveform.
*/
getValue(): Float32Array {
return this._analyser.getValue() as Float32Array;
}
/**
* The size of analysis. This must be a power of two in the range 16 to 16384.
* Determines the size of the array returned by {@link getValue}.
*/
get size(): PowerOfTwo {
return this._analyser.size;
}
set size(size) {
this._analyser.size = size;
}
}
================================================
FILE: Tone/component/channel/Channel.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { Offline } from "../../../test/helper/Offline.js";
import { PassAudio } from "../../../test/helper/PassAudio.js";
import { Signal } from "../../signal/Signal.js";
import { Channel } from "./Channel.js";
describe("Channel", () => {
BasicTests(Channel);
context("Channel", () => {
it("can pass volume and panning into the constructor", () => {
const channel = new Channel(-10, -1);
expect(channel.pan.value).to.be.closeTo(-1, 0.01);
expect(channel.volume.value).to.be.closeTo(-10, 0.01);
channel.dispose();
});
it("can pass in an object into the constructor", () => {
const channel = new Channel({
pan: 1,
volume: 6,
mute: false,
solo: true,
});
expect(channel.pan.value).to.be.closeTo(1, 0.01);
expect(channel.volume.value).to.be.closeTo(6, 0.01);
expect(channel.mute).to.be.false;
expect(channel.solo).to.be.true;
channel.dispose();
});
it("passes the incoming signal through", () => {
return PassAudio((input) => {
const channel = new Channel().toDestination();
input.connect(channel);
});
});
it("can mute the input", async () => {
const buffer = await Offline(() => {
const channel = new Channel(0).toDestination();
new Signal(1).connect(channel);
channel.mute = true;
});
expect(buffer.isSilent()).to.be.true;
});
it("reports itself as muted when either muted or another channel is soloed", () => {
const channelA = new Channel();
const channelB = new Channel();
channelB.solo = true;
expect(channelA.muted).to.be.true;
expect(channelB.muted).to.be.false;
channelB.mute = true;
expect(channelA.muted).to.be.true;
expect(channelB.muted).to.be.true;
channelA.dispose();
channelB.dispose();
});
describe("bus", () => {
it("can connect two channels together by name", () => {
return PassAudio((input) => {
const sendChannel = new Channel();
input.connect(sendChannel);
sendChannel.send("test");
const recvChannel = new Channel().toDestination();
recvChannel.receive("test");
});
});
});
});
});
================================================
FILE: Tone/component/channel/Channel.ts
================================================
import { Gain } from "../../core/context/Gain.js";
import { Param } from "../../core/context/Param.js";
import {
InputNode,
OutputNode,
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { AudioRange, Decibels } from "../../core/type/Units.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { readOnly } from "../../core/util/Interface.js";
import { PanVol } from "./PanVol.js";
import { Solo } from "./Solo.js";
export interface ChannelOptions extends ToneAudioNodeOptions {
pan: AudioRange;
volume: Decibels;
solo: boolean;
mute: boolean;
channelCount: number;
}
/**
* Channel provides a channel strip interface with volume, pan, solo and mute controls.
* @see {@link PanVol} and {@link Solo}
* @example
* // pan the incoming signal left and drop the volume 12db
* const channel = new Tone.Channel(-0.25, -12);
* @category Component
*/
export class Channel extends ToneAudioNode<ChannelOptions> {
readonly name: string = "Channel";
readonly input: InputNode;
readonly output: OutputNode;
/**
* The soloing interface
*/
private _solo: Solo;
/**
* The panning and volume node
*/
private _panVol: PanVol;
/**
* The L/R panning control. -1 = hard left, 1 = hard right.
* @min -1
* @max 1
*/
readonly pan: Param<"audioRange">;
/**
* The volume control in decibels.
*/
readonly volume: Param<"decibels">;
/**
* @param volume The output volume.
* @param pan the initial pan
*/
constructor(volume?: Decibels, pan?: AudioRange);
constructor(options?: Partial<ChannelOptions>);
constructor() {
const options = optionsFromArguments(Channel.getDefaults(), arguments, [
"volume",
"pan",
]);
super(options);
this._solo = this.input = new Solo({
solo: options.solo,
context: this.context,
});
this._panVol = this.output = new PanVol({
context: this.context,
pan: options.pan,
volume: options.volume,
mute: options.mute,
channelCount: options.channelCount,
});
this.pan = this._panVol.pan;
this.volume = this._panVol.volume;
this._solo.connect(this._panVol);
readOnly(this, ["pan", "volume"]);
}
static getDefaults(): ChannelOptions {
return Object.assign(ToneAudioNode.getDefaults(), {
pan: 0,
volume: 0,
mute: false,
solo: false,
channelCount: 1,
});
}
/**
* Solo/unsolo the channel. Soloing is only relative to other {@link Channel}s and {@link Solo} instances
*/
get solo(): boolean {
return this._solo.solo;
}
set solo(solo) {
this._solo.solo = solo;
}
/**
* If the current instance is muted, i.e. another instance is soloed,
* or the channel is muted
*/
get muted(): boolean {
return this._solo.muted || this.mute;
}
/**
* Mute/unmute the volume
*/
get mute(): boolean {
return this._panVol.mute;
}
set mute(mute) {
this._panVol.mute = mute;
}
/**
* Store the send/receive channels by name.
*/
private static buses: Map<string, Gain> = new Map();
/**
* Get the gain node belonging to the bus name. Create it if
* it doesn't exist
* @param name The bus name
*/
private _getBus(name: string): Gain {
if (!Channel.buses.has(name)) {
Channel.buses.set(name, new Gain({ context: this.context }));
}
return Channel.buses.get(name) as Gain;
}
/**
* Send audio to another channel using a string. `send` is a lot like
* {@link connect}, except it uses a string instead of an object. This can
* be useful in large applications to decouple sections since {@link send}
* and {@link receive} can be invoked separately in order to connect an object
* @param name The channel name to send the audio
* @param volume The amount of the signal to send.
* Defaults to 0db, i.e. send the entire signal
* @returns Returns the gain node of this connection.
*/
send(name: string, volume: Decibels = 0): Gain<"decibels"> {
const bus = this._getBus(name);
const sendKnob = new Gain({
context: this.context,
units: "decibels",
gain: volume,
});
this.connect(sendKnob);
sendKnob.connect(bus);
return sendKnob;
}
/**
* Receive audio from a channel which was connected with {@link send}.
* @param name The channel name to receive audio from.
*/
receive(name: string): this {
const bus = this._getBus(name);
bus.connect(this);
return this;
}
dispose(): this {
super.dispose();
this._panVol.dispose();
this.pan.dispose();
this.volume.dispose();
this._solo.dispose();
return this;
}
}
================================================
FILE: Tone/component/channel/CrossFade.test.ts
================================================
import { BasicTests } from "../../../test/helper/Basic.js";
import { connectFrom, connectTo } from "../../../test/helper/Connect.js";
import { ConstantOutput } from "../../../test/helper/ConstantOutput.js";
import { Signal } from "../../signal/Signal.js";
import { CrossFade } from "./CrossFade.js";
describe("CrossFade", () => {
BasicTests(CrossFade);
context("Fading", () => {
it("handles input and output connections", () => {
const comp = new CrossFade();
connectFrom().connect(comp.a);
connectFrom().connect(comp.b);
comp.connect(connectTo());
comp.dispose();
});
it("pass 100% of input 0", () => {
return ConstantOutput(
() => {
const crossFade = new CrossFade();
const drySignal = new Signal(10);
const wetSignal = new Signal(20);
drySignal.connect(crossFade.a);
wetSignal.connect(crossFade.b);
crossFade.fade.value = 0;
crossFade.toDestination();
},
10,
0.05
);
});
it("pass 100% of input 1", () => {
return ConstantOutput(
() => {
const crossFade = new CrossFade();
const drySignal = new Signal(10);
const wetSignal = new Signal(20);
drySignal.connect(crossFade.a);
wetSignal.connect(crossFade.b);
crossFade.fade.value = 1;
crossFade.toDestination();
},
20,
0.01
);
});
it("can mix two signals", () => {
return ConstantOutput(
() => {
const crossFade = new CrossFade();
const drySignal = new Signal(2);
const wetSignal = new Signal(1);
drySignal.connect(crossFade.a);
wetSignal.connect(crossFade.b);
crossFade.fade.value = 0.5;
crossFade.toDestination();
},
2.12,
0.01
);
});
});
});
================================================
FILE: Tone/component/channel/CrossFade.ts
================================================
import { Gain } from "../../core/context/Gain.js";
import {
connect,
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { NormalRange } from "../../core/type/Units.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { readOnly } from "../../core/util/Interface.js";
import { GainToAudio } from "../../signal/GainToAudio.js";
import { Signal } from "../../signal/Signal.js";
import { ToneConstantSource } from "../../signal/ToneConstantSource.js";
interface CrossFadeOptions extends ToneAudioNodeOptions {
fade: NormalRange;
}
/**
* Tone.Crossfade provides equal power fading between two inputs.
* More on crossfading technique [here](https://en.wikipedia.org/wiki/Fade_(audio_engineering)#Crossfading).
* ```
* +---------+
* +> input a +>--+
* +-----------+ +---------------------+ | | |
* | 1s signal +>--> stereoPannerNode L +>----> gain | |
* +-----------+ | | +---------+ |
* +-> pan R +>-+ | +--------+
* | +---------------------+ | +---> output +>
* +------+ | | +---------+ | +--------+
* | fade +>----+ | +> input b +>--+
* +------+ | | |
* +--> gain |
* +---------+
* ```
* @example
* const crossFade = new Tone.CrossFade().toDestination();
* // connect two inputs Tone.to a/b
* const inputA = new Tone.Oscillator(440, "square").connect(crossFade.a).start();
* const inputB = new Tone.Oscillator(440, "sine").connect(crossFade.b).start();
* // use the fade to control the mix between the two
* crossFade.fade.value = 0.5;
* @category Component
*/
export class CrossFade extends ToneAudioNode<CrossFadeOptions> {
readonly name: string = "CrossFade";
/**
* The crossfading is done by a StereoPannerNode
*/
private _panner: StereoPannerNode = this.context.createStereoPanner();
/**
* Split the output of the panner node into two values used to control the gains.
*/
private _split: ChannelSplitterNode = this.context.createChannelSplitter(2);
/**
* Convert the fade value into an audio range value so it can be connected
* to the panner.pan AudioParam
*/
private _g2a: GainToAudio = new GainToAudio({ context: this.context });
/**
* The constant source which is used to control the panner
*/
private _constant: ToneConstantSource;
/**
* The input which is at full level when fade = 0
*/
readonly a: Gain = new Gain({
context: this.context,
gain: 0,
});
/**
* The input which is at full level when fade = 1
*/
readonly b: Gain = new Gain({
context: this.context,
gain: 0,
});
/**
* The output is a mix between `a` and `b` at the ratio of `fade`
*/
readonly output: Gain = new Gain({ context: this.context });
/**
* CrossFade has no input, you must choose either `a` or `b`
*/
readonly input: undefined;
/**
* The mix between the two inputs. A fade value of 0
* will output 100% crossFade.a and
* a value of 1 will output 100% crossFade.b.
*/
readonly fade: Signal<"normalRange">;
protected _internalChannels = [this.a, this.b];
/**
* @param fade The initial fade value [0, 1].
*/
constructor(fade?: NormalRange);
constructor(options?: Partial<CrossFadeOptions>);
constructor() {
const options = optionsFromArguments(
CrossFade.getDefaults(),
arguments,
["fade"]
);
super(options);
this.fade = new Signal({
context: this.context,
units: "normalRange",
value: options.fade,
});
readOnly(this, "fade");
this._constant = new ToneConstantSource({
context: this.context,
offset: 1,
}).start();
this._constant.connect(this._panner);
this._panner.connect(this._split);
// this is necessary for standardized-audio-context
// doesn't make any difference for the native AudioContext
// https://github.com/chrisguttandin/standardized-audio-context/issues/647
this._panner.channelCount = 1;
this._panner.channelCountMode = "explicit";
connect(this._split, this.a.gain, 0);
connect(this._split, this.b.gain, 1);
this.fade.chain(this._g2a, this._panner.pan);
this.a.connect(this.output);
this.b.connect(this.output);
}
static getDefaults(): CrossFadeOptions {
return Object.assign(ToneAudioNode.getDefaults(), {
fade: 0.5,
});
}
dispose(): this {
super.dispose();
this.a.dispose();
this.b.dispose();
this.output.dispose();
this.fade.dispose();
this._g2a.dispose();
this._panner.disconnect();
this._split.disconnect();
this._constant.dispose();
return this;
}
}
================================================
FILE: Tone/component/channel/Merge.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { connectFrom, connectTo } from "../../../test/helper/Connect.js";
import { Offline } from "../../../test/helper/Offline.js";
import { PassAudio } from "../../../test/helper/PassAudio.js";
import { Signal } from "../../signal/Signal.js";
import { Merge } from "./Merge.js";
describe("Merge", () => {
BasicTests(Merge);
context("Merging", () => {
it("handles input and output connections", () => {
const merge = new Merge();
connectFrom().connect(merge);
merge.connect(connectTo());
merge.dispose();
});
it("defaults to two channels", () => {
const merge = new Merge();
expect(merge.numberOfInputs).to.equal(2);
merge.dispose();
});
it("can pass in more channels", () => {
const merge = new Merge(4);
expect(merge.numberOfInputs).to.equal(4);
connectFrom().connect(merge, 0, 0);
connectFrom().connect(merge, 0, 1);
connectFrom().connect(merge, 0, 2);
connectFrom().connect(merge, 0, 3);
merge.dispose();
});
it("passes the incoming signal through", () => {
return PassAudio((input) => {
const merge = new Merge().toDestination();
input.connect(merge);
});
});
it("merge two signal into one stereo signal", async () => {
const buffer = await Offline(
() => {
const sigL = new Signal(1);
const sigR = new Signal(2);
const merger = new Merge();
sigL.connect(merger, 0, 0);
sigR.connect(merger, 0, 1);
merger.toDestination();
},
0.1,
2
);
expect(buffer.toArray()[0][0]).to.be.closeTo(1, 0.001);
expect(buffer.toArray()[1][0]).to.be.closeTo(2, 0.001);
});
});
});
================================================
FILE: Tone/component/channel/Merge.ts
================================================
import {
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { Positive } from "../../core/type/Units.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
interface MergeOptions extends ToneAudioNodeOptions {
channels: Positive;
}
/**
* Merge brings multiple mono input channels into a single multichannel output channel.
*
* @example
* const merge = new Tone.Merge().toDestination();
* // routing a sine tone in the left channel
* const osc = new Tone.Oscillator().connect(merge, 0, 0).start();
* // and noise in the right channel
* const noise = new Tone.Noise().connect(merge, 0, 1).start();;
* @category Component
*/
export class Merge extends ToneAudioNode<MergeOptions> {
readonly name: string = "Merge";
/**
* The merger node for the channels.
*/
private _merger: ChannelMergerNode;
/**
* The output is the input channels combined into a single (multichannel) output
*/
readonly output: ChannelMergerNode;
/**
* Multiple input connections combine into a single output.
*/
readonly input: ChannelMergerNode;
/**
* @param channels The number of channels to merge.
*/
constructor(channels?: Positive);
constructor(options?: Partial<MergeOptions>);
constructor() {
const options = optionsFromArguments(Merge.getDefaults(), arguments, [
"channels",
]);
super(options);
this._merger =
this.output =
this.input =
this.context.createChannelMerger(options.channels);
}
static getDefaults(): MergeOptions {
return Object.assign(ToneAudioNode.getDefaults(), {
channels: 2,
});
}
dispose(): this {
super.dispose();
this._merger.disconnect();
return this;
}
}
================================================
FILE: Tone/component/channel/MidSideMerge.test.ts
================================================
import { BasicTests } from "../../../test/helper/Basic.js";
import { connectFrom, connectTo } from "../../../test/helper/Connect.js";
import { PassAudio } from "../../../test/helper/PassAudio.js";
import { MidSideMerge } from "./MidSideMerge.js";
describe("MidSideMerge", () => {
BasicTests(MidSideMerge);
context("Merging", () => {
it("handles inputs and outputs", () => {
const merge = new MidSideMerge();
merge.connect(connectTo());
connectFrom().connect(merge.mid);
connectFrom().connect(merge.side);
merge.dispose();
});
it("passes the mid signal through", () => {
return PassAudio((input) => {
const merge = new MidSideMerge().toDestination();
input.connect(merge.mid);
});
});
});
});
================================================
FILE: Tone/component/channel/MidSideMerge.ts
================================================
import { Gain } from "../../core/context/Gain.js";
import {
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { Add } from "../../signal/Add.js";
import { Multiply } from "../../signal/Multiply.js";
import { Subtract } from "../../signal/Subtract.js";
import { Merge } from "./Merge.js";
export type MidSideMergeOptions = ToneAudioNodeOptions;
/**
* MidSideMerge merges the mid and side signal after they've been separated by {@link MidSideSplit}
* ```
* Mid = (Left+Right)/sqrt(2); // obtain mid-signal from left and right
* Side = (Left-Right)/sqrt(2); // obtain side-signal from left and right
* ```
* @category Component
*/
export class MidSideMerge extends ToneAudioNode<MidSideMergeOptions> {
readonly name: string = "MidSideMerge";
/**
* There is no input, connect sources to either {@link mid} or {@link side} inputs.
*/
readonly input: undefined;
/**
* The merged signal
*/
readonly output: Merge;
/**
* Merge the incoming signal into left and right channels
*/
private _merge: Merge;
/**
* The "mid" input.
*/
readonly mid: ToneAudioNode;
/**
* The "side" input.
*/
readonly side: ToneAudioNode;
/**
* Recombine the mid/side into Left
*/
private _left: Add;
/**
* Recombine the mid/side into Right
*/
private _right: Subtract;
/**
* Multiply the right by sqrt(1/2)
*/
private _leftMult: Multiply;
/**
* Multiply the left by sqrt(1/2)
*/
private _rightMult: Multiply;
constructor(options?: Partial<MidSideMergeOptions>);
constructor() {
super(optionsFromArguments(MidSideMerge.getDefaults(), arguments));
this.mid = new Gain({ context: this.context });
this.side = new Gain({ context: this.context });
this._left = new Add({ context: this.context });
this._leftMult = new Multiply({
context: this.context,
value: Math.SQRT1_2,
});
this._right = new Subtract({ context: this.context });
this._rightMult = new Multiply({
context: this.context,
value: Math.SQRT1_2,
});
this._merge = this.output = new Merge({ context: this.context });
this.mid.fan(this._left);
this.side.connect(this._left.addend);
this.mid.connect(this._right);
this.side.connect(this._right.subtrahend);
this._left.connect(this._leftMult);
this._right.connect(this._rightMult);
this._leftMult.connect(this._merge, 0, 0);
this._rightMult.connect(this._merge, 0, 1);
}
dispose(): this {
super.dispose();
this.mid.dispose();
this.side.dispose();
this._leftMult.dispose();
this._rightMult.dispose();
this._left.dispose();
this._right.dispose();
return this;
}
}
================================================
FILE: Tone/component/channel/MidSideSplit.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { connectFrom, connectTo } from "../../../test/helper/Connect.js";
import { Offline } from "../../../test/helper/Offline.js";
import { Signal } from "../../signal/Signal.js";
import { Merge } from "./Merge.js";
import { MidSideMerge } from "./MidSideMerge.js";
import { MidSideSplit } from "./MidSideSplit.js";
describe("MidSideSplit", () => {
BasicTests(MidSideSplit);
context("Splitting", () => {
it("handles inputs and outputs", () => {
const split = new MidSideSplit();
connectFrom().connect(split);
split.mid.connect(connectTo());
split.side.connect(connectTo());
split.dispose();
});
it("mid is if both L and R are the same", async () => {
const buffer = await Offline(() => {
const split = new MidSideSplit();
split.mid.toDestination();
const merge = new Merge().connect(split);
new Signal(0.5).connect(merge, 0, 0);
new Signal(0.5).connect(merge, 0, 1);
});
expect(buffer.min()).to.be.closeTo(0.707, 0.01);
expect(buffer.max()).to.be.closeTo(0.707, 0.01);
});
it("side is 0 if both L and R are the same", async () => {
const buffer = await Offline(() => {
const split = new MidSideSplit();
split.side.toDestination();
const merge = new Merge().connect(split);
new Signal(0.5).connect(merge, 0, 0);
new Signal(0.5).connect(merge, 0, 1);
});
expect(buffer.min()).to.be.closeTo(0, 0.01);
expect(buffer.max()).to.be.closeTo(0, 0.01);
});
it("mid is 0 if both L and R opposites", async () => {
const buffer = await Offline(() => {
const split = new MidSideSplit();
split.mid.toDestination();
const merge = new Merge().connect(split);
new Signal(-1).connect(merge, 0, 0);
new Signal(1).connect(merge, 0, 1);
});
expect(buffer.min()).to.be.closeTo(0, 0.01);
expect(buffer.max()).to.be.closeTo(0, 0.01);
});
it("can decompose and reconstruct a signal", async () => {
const buffer = await Offline(
() => {
const midSideMerge = new MidSideMerge().toDestination();
const split = new MidSideSplit();
split.mid.connect(midSideMerge.mid);
split.side.connect(midSideMerge.side);
const merge = new Merge().connect(split);
new Signal(0.2).connect(merge, 0, 0);
new Signal(0.4).connect(merge, 0, 1);
},
0.1,
2
);
buffer
.toArray()[0]
.forEach((l) => expect(l).to.be.closeTo(0.2, 0.01));
buffer
.toArray()[1]
.forEach((r) => expect(r).to.be.closeTo(0.4, 0.01));
});
});
});
================================================
FILE: Tone/component/channel/MidSideSplit.ts
================================================
import {
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { Add } from "../../signal/Add.js";
import { Multiply } from "../../signal/Multiply.js";
import { Subtract } from "../../signal/Subtract.js";
import { Split } from "./Split.js";
export type MidSideSplitOptions = ToneAudioNodeOptions;
/**
* Mid/Side processing separates the the 'mid' signal (which comes out of both the left and the right channel)
* and the 'side' (which only comes out of the the side channels).
* ```
* Mid = (Left+Right)/sqrt(2); // obtain mid-signal from left and right
* Side = (Left-Right)/sqrt(2); // obtain side-signal from left and right
* ```
* @category Component
*/
export class MidSideSplit extends ToneAudioNode<MidSideSplitOptions> {
readonly name: string = "MidSideSplit";
readonly input: Split;
/**
* There is no output node, use either {@link mid} or {@link side} outputs.
*/
readonly output: undefined;
/**
* Split the incoming signal into left and right channels
*/
private _split: Split;
/**
* Sums the left and right channels
*/
private _midAdd: Add;
/**
* Subtract left and right channels.
*/
private _sideSubtract: Subtract;
/**
* The "mid" output. `(Left+Right)/sqrt(2)`
*/
readonly mid: ToneAudioNode;
/**
* The "side" output. `(Left-Right)/sqrt(2)`
*/
readonly side: ToneAudioNode;
constructor(options?: Partial<MidSideSplitOptions>);
constructor() {
super(optionsFromArguments(MidSideSplit.getDefaults(), arguments));
this._split = this.input = new Split({
channels: 2,
context: this.context,
});
this._midAdd = new Add({ context: this.context });
this.mid = new Multiply({
context: this.context,
value: Math.SQRT1_2,
});
this._sideSubtract = new Subtract({ context: this.context });
this.side = new Multiply({
context: this.context,
value: Math.SQRT1_2,
});
this._split.connect(this._midAdd, 0);
this._split.connect(this._midAdd.addend, 1);
this._split.connect(this._sideSubtract, 0);
this._split.connect(this._sideSubtract.subtrahend, 1);
this._midAdd.connect(this.mid);
this._sideSubtract.connect(this.side);
}
dispose(): this {
super.dispose();
this.mid.dispose();
this.side.dispose();
this._midAdd.dispose();
this._sideSubtract.dispose();
this._split.dispose();
return this;
}
}
================================================
FILE: Tone/component/channel/Mono.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { Offline } from "../../../test/helper/Offline.js";
import { StereoSignal } from "../../../test/helper/StereoSignal.js";
import { Signal } from "../../signal/Signal.js";
import { Mono } from "./Mono.js";
describe("Mono", () => {
BasicTests(Mono);
context("Mono", () => {
it("Makes a mono signal in both channels", async () => {
const buffer = await Offline(
() => {
const mono = new Mono().toDestination();
const signal = new Signal(2).connect(mono);
},
0.1,
2
);
expect(buffer.toArray()[0][0]).to.equal(2);
expect(buffer.toArray()[1][0]).to.equal(2);
expect(buffer.toArray()[0][100]).to.equal(2);
expect(buffer.toArray()[1][100]).to.equal(2);
expect(buffer.toArray()[0][1000]).to.equal(2);
expect(buffer.toArray()[1][1000]).to.equal(2);
});
it("Sums a stereo signal into a mono signal", async () => {
const buffer = await Offline(
() => {
const mono = new Mono().toDestination();
const signal = StereoSignal(2, 2).connect(mono);
},
0.1,
2
);
expect(buffer.toArray()[0][0]).to.equal(2);
expect(buffer.toArray()[1][0]).to.equal(2);
expect(buffer.toArray()[0][100]).to.equal(2);
expect(buffer.toArray()[1][100]).to.equal(2);
expect(buffer.toArray()[0][1000]).to.equal(2);
expect(buffer.toArray()[1][1000]).to.equal(2);
});
});
});
================================================
FILE: Tone/component/channel/Mono.ts
================================================
import { Gain } from "../../core/context/Gain.js";
import {
OutputNode,
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { Merge } from "./Merge.js";
export type MonoOptions = ToneAudioNodeOptions;
/**
* Mono coerces the incoming mono or stereo signal into a mono signal
* where both left and right channels have the same value. This can be useful
* for [stereo imaging](https://en.wikipedia.org/wiki/Stereo_imaging).
* @category Component
*/
export class Mono extends ToneAudioNode<MonoOptions> {
readonly name: string = "Mono";
/**
* merge the signal
*/
private _merge: Merge;
/**
* The summed output of the multiple inputs
*/
readonly output: OutputNode;
/**
* The stereo signal to sum to mono
*/
readonly input: Gain;
constructor(options?: Partial<MonoOptions>);
constructor() {
super(optionsFromArguments(Mono.getDefaults(), arguments));
this.input = new Gain({ context: this.context });
this._merge = this.output = new Merge({
channels: 2,
context: this.context,
});
this.input.connect(this._merge, 0, 0);
this.input.connect(this._merge, 0, 1);
}
dispose(): this {
super.dispose();
this._merge.dispose();
this.input.dispose();
return this;
}
}
================================================
FILE: Tone/component/channel/MultibandSplit.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { connectFrom, connectTo } from "../../../test/helper/Connect.js";
import { PassAudio } from "../../../test/helper/PassAudio.js";
import { MultibandSplit } from "./MultibandSplit.js";
describe("MultibandSplit", () => {
BasicTests(MultibandSplit);
it("handles input and output connections", () => {
const split = new MultibandSplit();
connectFrom().connect(split);
split.low.connect(connectTo());
split.mid.connect(connectTo());
split.high.connect(connectTo());
split.dispose();
});
it("can be constructed with an object", () => {
const split = new MultibandSplit({
Q: 8,
highFrequency: 2700,
lowFrequency: 500,
});
expect(split.lowFrequency.value).to.be.closeTo(500, 0.01);
expect(split.highFrequency.value).to.be.closeTo(2700, 0.01);
expect(split.Q.value).to.be.closeTo(8, 0.01);
split.dispose();
});
it("can be get and set through object", () => {
const split = new MultibandSplit();
split.set({
Q: 4,
lowFrequency: 250,
});
expect(split.get().Q).to.be.closeTo(4, 0.1);
expect(split.get().lowFrequency).to.be.closeTo(250, 0.01);
split.dispose();
});
it("passes the incoming signal through low", () => {
return PassAudio((input) => {
const split = new MultibandSplit().low.toDestination();
input.connect(split);
});
});
it("passes the incoming signal through mid", () => {
return PassAudio((input) => {
const split = new MultibandSplit().mid.toDestination();
input.connect(split);
});
});
it("passes the incoming signal through high", () => {
return PassAudio((input) => {
const split = new MultibandSplit({
highFrequency: 10,
lowFrequency: 5,
}).high.toDestination();
input.connect(split);
});
});
});
================================================
FILE: Tone/component/channel/MultibandSplit.ts
================================================
import { Gain } from "../../core/context/Gain.js";
import {
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { Frequency, Positive } from "../../core/type/Units.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { readOnly, writable } from "../../core/util/Interface.js";
import { Signal } from "../../signal/Signal.js";
import { Filter } from "../filter/Filter.js";
interface MultibandSplitOptions extends ToneAudioNodeOptions {
Q: Positive;
lowFrequency: Frequency;
highFrequency: Frequency;
}
/**
* Split the incoming signal into three bands (low, mid, high)
* with two crossover frequency controls.
* ```
* +----------------------+
* +-> input < lowFrequency +------------------> low
* | +----------------------+
* |
* | +--------------------------------------+
* input ---+-> lowFrequency < input < highFrequency +--> mid
* | +--------------------------------------+
* |
* | +-----------------------+
* +-> highFrequency < input +-----------------> high
* +-----------------------+
* ```
* @category Component
*/
export class MultibandSplit extends ToneAudioNode<MultibandSplitOptions> {
readonly name: string = "MultibandSplit";
/**
* the input
*/
readonly input = new Gain({ context: this.context });
/**
* no output node, use either low, mid or high outputs
*/
readonly output = undefined;
/**
* The low band.
*/
readonly low = new Filter({
context: this.context,
frequency: 0,
type: "lowpass",
});
/**
* the lower filter of the mid band
*/
private _lowMidFilter = new Filter({
context: this.context,
frequency: 0,
type: "highpass",
});
/**
* The mid band output.
*/
readonly mid = new Filter({
context: this.context,
frequency: 0,
type: "lowpass",
});
/**
* The high band output.
*/
readonly high = new Filter({
context: this.context,
frequency: 0,
type: "highpass",
});
/**
* The low/mid crossover frequency.
*/
readonly lowFrequency: Signal<"frequency">;
/**
* The mid/high crossover frequency.
*/
readonly highFrequency: Signal<"frequency">;
protected _internalChannels = [this.low, this.mid, this.high];
/**
* The Q or Quality of the filter
*/
readonly Q: Signal<"positive">;
/**
* @param lowFrequency the low/mid crossover frequency
* @param highFrequency the mid/high crossover frequency
*/
constructor(lowFrequency?: Frequency, highFrequency?: Frequency);
constructor(options?: Partial<MultibandSplitOptions>);
constructor() {
const options = optionsFromArguments(
MultibandSplit.getDefaults(),
arguments,
["lowFrequency", "highFrequency"]
);
super(options);
this.lowFrequency = new Signal({
context: this.context,
units: "frequency",
value: options.lowFrequency,
});
this.highFrequency = new Signal({
context: this.context,
units: "frequency",
value: options.highFrequency,
});
this.Q = new Signal({
context: this.context,
units: "positive",
value: options.Q,
});
this.input.fan(this.low, this.high);
this.input.chain(this._lowMidFilter, this.mid);
// the frequency control signal
this.lowFrequency.fan(this.low.frequency, this._lowMidFilter.frequency);
this.highFrequency.fan(this.mid.frequency, this.high.frequency);
// the Q value
this.Q.connect(this.low.Q);
this.Q.connect(this._lowMidFilter.Q);
this.Q.connect(this.mid.Q);
this.Q.connect(this.high.Q);
readOnly(this, ["high", "mid", "low", "highFrequency", "lowFrequency"]);
}
static getDefaults(): MultibandSplitOptions {
return Object.assign(ToneAudioNode.getDefaults(), {
Q: 1,
highFrequency: 2500,
lowFrequency: 400,
});
}
/**
* Clean up.
*/
dispose(): this {
super.dispose();
writable(this, ["high", "mid", "low", "highFrequency", "lowFrequency"]);
this.low.dispose();
this._lowMidFilter.dispose();
this.mid.dispose();
this.high.dispose();
this.lowFrequency.dispose();
this.highFrequency.dispose();
this.Q.dispose();
return this;
}
}
================================================
FILE: Tone/component/channel/PanVol.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { Offline } from "../../../test/helper/Offline.js";
import { PassAudio } from "../../../test/helper/PassAudio.js";
import { Signal } from "../../signal/Signal.js";
import { PanVol } from "./PanVol.js";
describe("PanVol", () => {
BasicTests(PanVol);
context("Pan and Volume", () => {
it("can be constructed with the panning and volume value", () => {
const panVol = new PanVol(0.3, -12);
expect(panVol.pan.value).to.be.closeTo(0.3, 0.001);
expect(panVol.volume.value).to.be.closeTo(-12, 0.1);
panVol.dispose();
});
it("can be constructed with an options object", () => {
const panVol = new PanVol({
mute: true,
pan: 0.2,
});
expect(panVol.pan.value).to.be.closeTo(0.2, 0.001);
expect(panVol.mute).to.be.true;
panVol.dispose();
});
it("can set/get with an object", () => {
const panVol = new PanVol();
panVol.set({
volume: -10,
});
expect(panVol.get().volume).to.be.closeTo(-10, 0.1);
panVol.dispose();
});
it("passes the incoming signal through", () => {
return PassAudio((input) => {
const panVol = new PanVol().toDestination();
input.connect(panVol);
});
});
it("can mute the volume", async () => {
const buffer = await Offline(() => {
const vol = new PanVol(0).toDestination();
new Signal(1).connect(vol);
vol.mute = true;
});
expect(buffer.isSilent()).to.be.true;
});
});
});
================================================
FILE: Tone/component/channel/PanVol.ts
================================================
import { Param } from "../../core/context/Param.js";
import {
InputNode,
OutputNode,
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { AudioRange, Decibels } from "../../core/type/Units.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { readOnly } from "../../core/util/Interface.js";
import { Panner } from "./Panner.js";
import { Volume } from "./Volume.js";
export interface PanVolOptions extends ToneAudioNodeOptions {
pan: AudioRange;
volume: Decibels;
mute: boolean;
channelCount: number;
}
/**
* PanVol is a Tone.Panner and Tone.Volume in one.
* @example
* // pan the incoming signal left and drop the volume
* const panVol = new Tone.PanVol(-0.25, -12).toDestination();
* const osc = new Tone.Oscillator().connect(panVol).start();
* @category Component
*/
export class PanVol extends ToneAudioNode<PanVolOptions> {
readonly name: string = "PanVol";
readonly input: InputNode;
readonly output: OutputNode;
/**
* The panning node
*/
private _panner: Panner;
/**
* The L/R panning control. -1 = hard left, 1 = hard right.
* @min -1
* @max 1
*/
readonly pan: Param<"audioRange">;
/**
* The volume node
*/
private _volume: Volume;
/**
* The volume control in decibels.
*/
readonly volume: Param<"decibels">;
/**
* @param pan the initial pan
* @param volume The output volume.
*/
constructor(pan?: AudioRange, volume?: Decibels);
constructor(options?: Partial<PanVolOptions>);
constructor() {
const options = optionsFromArguments(PanVol.getDefaults(), arguments, [
"pan",
"volume",
]);
super(options);
this._panner = this.input = new Panner({
context: this.context,
pan: options.pan,
channelCount: options.channelCount,
});
this.pan = this._panner.pan;
this._volume = this.output = new Volume({
context: this.context,
volume: options.volume,
});
this.volume = this._volume.volume;
// connections
this._panner.connect(this._volume);
this.mute = options.mute;
readOnly(this, ["pan", "volume"]);
}
static getDefaults(): PanVolOptions {
return Object.assign(ToneAudioNode.getDefaults(), {
mute: false,
pan: 0,
volume: 0,
channelCount: 1,
});
}
/**
* Mute/unmute the volume
*/
get mute(): boolean {
return this._volume.mute;
}
set mute(mute) {
this._volume.mute = mute;
}
dispose(): this {
super.dispose();
this._panner.dispose();
this.pan.dispose();
this._volume.dispose();
this.volume.dispose();
return this;
}
}
================================================
FILE: Tone/component/channel/Panner.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { Offline } from "../../../test/helper/Offline.js";
import { PassAudio } from "../../../test/helper/PassAudio.js";
import { Signal } from "../../signal/Signal.js";
import { Panner } from "./Panner.js";
describe("Panner", () => {
BasicTests(Panner);
context("Panning", () => {
it("can be constructed with the panning value", () => {
const panner = new Panner(0.3);
expect(panner.pan.value).to.be.closeTo(0.3, 0.001);
panner.dispose();
});
it("can be constructed with an options object", () => {
const panner = new Panner({
pan: 0.5,
});
expect(panner.pan.value).to.be.closeTo(0.5, 0.001);
panner.dispose();
});
it("passes the incoming signal through", () => {
return PassAudio((input) => {
const panner = new Panner().toDestination();
input.connect(panner);
});
});
it("pans hard left when the pan is set to -1", async () => {
const buffer = await Offline(
() => {
const panner = new Panner(-1).toDestination();
new Signal(1).connect(panner);
},
0.1,
2
);
const l = buffer.toArray()[0];
const r = buffer.toArray()[1];
expect(l[0]).to.be.closeTo(1, 0.01);
expect(r[0]).to.be.closeTo(0, 0.01);
});
it("pans hard right when the pan is set to 1", async () => {
const buffer = await Offline(
() => {
const panner = new Panner(1).toDestination();
new Signal(1).connect(panner);
},
0.1,
2
);
const l = buffer.toArray()[0];
const r = buffer.toArray()[1];
expect(l[0]).to.be.closeTo(0, 0.01);
expect(r[0]).to.be.closeTo(1, 0.01);
});
it("mixes the signal in equal power when panned center", async () => {
const buffer = await Offline(
() => {
const panner = new Panner(0).toDestination();
new Signal(1).connect(panner);
},
0.1,
2
);
const l = buffer.toArray()[0];
const r = buffer.toArray()[1];
expect(l[0]).to.be.closeTo(0.707, 0.01);
expect(r[0]).to.be.closeTo(0.707, 0.01);
});
it("can chain two panners when channelCount is 2", async () => {
const buffer = await Offline(
() => {
const panner1 = new Panner({
channelCount: 2,
}).toDestination();
const panner0 = new Panner(-1).connect(panner1);
new Signal(1).connect(panner0);
},
0.1,
2
);
const l = buffer.toArray()[0];
const r = buffer.toArray()[1];
expect(l[0]).to.be.closeTo(1, 0.01);
expect(r[0]).to.be.closeTo(0, 0.01);
});
});
});
================================================
FILE: Tone/component/channel/Panner.ts
================================================
import { Param } from "../../core/context/Param.js";
import {
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { AudioRange } from "../../core/type/Units.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { readOnly } from "../../core/util/Interface.js";
interface TonePannerOptions extends ToneAudioNodeOptions {
pan: AudioRange;
channelCount: number;
}
/**
* Panner is an equal power Left/Right Panner. It is a wrapper around the StereoPannerNode.
* @example
* return Tone.Offline(() => {
* // move the input signal from right to left
* const panner = new Tone.Panner(1).toDestination();
* panner.pan.rampTo(-1, 0.5);
* const osc = new Tone.Oscillator(100).connect(panner).start();
* }, 0.5, 2);
* @category Component
*/
export class Panner extends ToneAudioNode<TonePannerOptions> {
readonly name: string = "Panner";
/**
* the panner node
*/
private _panner: StereoPannerNode = this.context.createStereoPanner();
readonly input: StereoPannerNode = this._panner;
readonly output: StereoPannerNode = this._panner;
/**
* The pan control. -1 = hard left, 1 = hard right.
* @min -1
* @max 1
* @example
* return Tone.Offline(() => {
* // pan hard right
* const panner = new Tone.Panner(1).toDestination();
* // pan hard left
* panner.pan.setValueAtTime(-1, 0.25);
* const osc = new Tone.Oscillator(50, "triangle").connect(panner).start();
* }, 0.5, 2);
*/
readonly pan: Param<"audioRange">;
constructor(options?: Partial<TonePannerOptions>);
/**
* @param pan The initial panner value (Defaults to 0 = "center").
*/
constructor(pan?: AudioRange);
constructor() {
const options = optionsFromArguments(Panner.getDefaults(), arguments, [
"pan",
]);
super(options);
this.pan = new Param({
context: this.context,
param: this._panner.pan,
value: options.pan,
minValue: -1,
maxValue: 1,
});
// this is necessary for standardized-audio-context
// doesn't make any difference for the native AudioContext
// https://github.com/chrisguttandin/standardized-audio-context/issues/647
this._panner.channelCount = options.channelCount;
this._panner.channelCountMode = "explicit";
// initial value
readOnly(this, "pan");
}
static getDefaults(): TonePannerOptions {
return Object.assign(ToneAudioNode.getDefaults(), {
pan: 0,
channelCount: 1,
});
}
dispose(): this {
super.dispose();
this._panner.disconnect();
this.pan.dispose();
return this;
}
}
================================================
FILE: Tone/component/channel/Panner3D.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { PassAudio } from "../../../test/helper/PassAudio.js";
import { Panner3D } from "./Panner3D.js";
describe("Panner3D", () => {
BasicTests(Panner3D);
it("passes the incoming signal through", () => {
return PassAudio((input) => {
const panner = new Panner3D().toDestination();
input.connect(panner);
});
});
it("can get/set the position individually", () => {
const panner = new Panner3D();
panner.positionX.value = 10;
expect(panner.positionX.value).to.equal(10);
panner.positionY.value = 20;
expect(panner.positionY.value).to.equal(20);
panner.positionZ.value = -1;
expect(panner.positionZ.value).to.equal(-1);
panner.dispose();
});
it("can get/set the orientation individually", () => {
const panner = new Panner3D();
panner.orientationX.value = 2;
expect(panner.orientationX.value).to.equal(2);
panner.orientationY.value = 4;
expect(panner.orientationY.value).to.equal(4);
panner.orientationZ.value = -3;
expect(panner.orientationZ.value).to.equal(-3);
panner.dispose();
});
it("can get/set the position through setPosition", () => {
const panner = new Panner3D();
panner.setPosition(3, -11, 2);
expect(panner.positionX.value).to.equal(3);
expect(panner.positionY.value).to.equal(-11);
expect(panner.positionZ.value).to.equal(2);
panner.dispose();
});
it("can get/set the orientation through setOrientation", () => {
const panner = new Panner3D();
panner.setOrientation(2, -1, 0.5);
expect(panner.orientationX.value).to.equal(2);
expect(panner.orientationY.value).to.equal(-1);
expect(panner.orientationZ.value).to.equal(0.5);
panner.dispose();
});
it("can get/set all of the other attributes", () => {
const values = {
coneInnerAngle: 120,
coneOuterAngle: 280,
coneOuterGain: 0.3,
distanceModel: "exponential",
maxDistance: 10002,
panningModel: "HRTF",
refDistance: 0.3,
rolloffFactor: 3,
};
const panner = new Panner3D();
for (const v in values) {
if (v in values) {
panner[v] = values[v];
expect(panner[v]).to.equal(values[v]);
}
}
panner.dispose();
});
});
================================================
FILE: Tone/component/channel/Panner3D.ts
================================================
import "../../core/context/Listener.js";
import { Param } from "../../core/context/Param.js";
import {
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { Degrees, GainFactor } from "../../core/type/Units.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
export interface Panner3DOptions extends ToneAudioNodeOptions {
coneInnerAngle: Degrees;
coneOuterAngle: Degrees;
coneOuterGain: GainFactor;
distanceModel: DistanceModelType;
maxDistance: number;
orientationX: number;
orientationY: number;
orientationZ: number;
panningModel: PanningModelType;
positionX: number;
positionY: number;
positionZ: number;
refDistance: number;
rolloffFactor: number;
}
/**
* A spatialized panner node which supports equalpower or HRTF panning.
* @category Component
*/
export class Panner3D extends ToneAudioNode<Panner3DOptions> {
readonly name: string = "Panner3D";
/**
* The panning object
*/
private _panner: PannerNode;
readonly input: PannerNode;
readonly output: PannerNode;
readonly positionX: Param<"number">;
readonly positionY: Param<"number">;
readonly positionZ: Param<"number">;
readonly orientationX: Param<"number">;
readonly orientationY: Param<"number">;
readonly orientationZ: Param<"number">;
/**
* @param positionX The initial x position.
* @param positionY The initial y position.
* @param positionZ The initial z position.
*/
constructor(positionX: number, positionY: number, positionZ: number);
constructor(options?: Partial<Panner3DOptions>);
constructor() {
const options = optionsFromArguments(
Panner3D.getDefaults(),
arguments,
["positionX", "positionY", "positionZ"]
);
super(options);
this._panner = this.input = this.output = this.context.createPanner();
// set some values
this.panningModel = options.panningModel;
this.maxDistance = options.maxDistance;
this.distanceModel = options.distanceModel;
this.coneOuterGain = options.coneOuterGain;
this.coneOuterAngle = options.coneOuterAngle;
this.coneInnerAngle = options.coneInnerAngle;
this.refDistance = options.refDistance;
this.rolloffFactor = options.rolloffFactor;
this.positionX = new Param({
context: this.context,
param: this._panner.positionX,
value: options.positionX,
});
this.positionY = new Param({
context: this.context,
param: this._panner.positionY,
value: options.positionY,
});
this.positionZ = new Param({
context: this.context,
param: this._panner.positionZ,
value: options.positionZ,
});
this.orientationX = new Param({
context: this.context,
param: this._panner.orientationX,
value: options.orientationX,
});
this.orientationY = new Param({
context: this.context,
param: this._panner.orientationY,
value: options.orientationY,
});
this.orientationZ = new Param({
context: this.context,
param: this._panner.orientationZ,
value: options.orientationZ,
});
}
static getDefaults(): Panner3DOptions {
return Object.assign(ToneAudioNode.getDefaults(), {
coneInnerAngle: 360,
coneOuterAngle: 360,
coneOuterGain: 0,
distanceModel: "inverse" as DistanceModelType,
maxDistance: 10000,
orientationX: 0,
orientationY: 0,
orientationZ: 0,
panningModel: "equalpower" as PanningModelType,
positionX: 0,
positionY: 0,
positionZ: 0,
refDistance: 1,
rolloffFactor: 1,
});
}
/**
* Sets the position of the source in 3d space.
*/
setPosition(x: number, y: number, z: number): this {
this.positionX.value = x;
this.positionY.value = y;
this.positionZ.value = z;
return this;
}
/**
* Sets the orientation of the source in 3d space.
*/
setOrientation(x: number, y: number, z: number): this {
this.orientationX.value = x;
this.orientationY.value = y;
this.orientationZ.value = z;
return this;
}
/**
* The panning model. Either "equalpower" or "HRTF".
*/
get panningModel(): PanningModelType {
return this._panner.panningModel;
}
set panningModel(val) {
this._panner.panningModel = val;
}
/**
* A reference distance for reducing volume as source move further from the listener
*/
get refDistance(): number {
return this._panner.refDistance;
}
set refDistance(val) {
this._panner.refDistance = val;
}
/**
* Describes how quickly the volume is reduced as source moves away from listener.
*/
get rolloffFactor(): number {
return this._panner.rolloffFactor;
}
set rolloffFactor(val) {
this._panner.rolloffFactor = val;
}
/**
* The distance model used by, "linear", "inverse", or "exponential".
*/
get distanceModel(): DistanceModelType {
return this._panner.distanceModel;
}
set distanceModel(val) {
this._panner.distanceModel = val;
}
/**
* The angle, in degrees, inside of which there will be no volume reduction
*/
get coneInnerAngle(): Degrees {
return this._panner.coneInnerAngle;
}
set coneInnerAngle(val) {
this._panner.coneInnerAngle = val;
}
/**
* The angle, in degrees, outside of which the volume will be reduced
* to a constant value of coneOuterGain
*/
get coneOuterAngle(): Degrees {
return this._panner.coneOuterAngle;
}
set coneOuterAngle(val) {
this._panner.coneOuterAngle = val;
}
/**
* The gain outside of the coneOuterAngle
*/
get coneOuterGain(): GainFactor {
return this._panner.coneOuterGain;
}
set coneOuterGain(val) {
this._panner.coneOuterGain = val;
}
/**
* The maximum distance between source and listener,
* after which the volume will not be reduced any further.
*/
get maxDistance(): number {
return this._panner.maxDistance;
}
set maxDistance(val) {
this._panner.maxDistance = val;
}
dispose(): this {
super.dispose();
this._panner.disconnect();
this.orientationX.dispose();
this.orientationY.dispose();
this.orientationZ.dispose();
this.positionX.dispose();
this.positionY.dispose();
this.positionZ.dispose();
return this;
}
}
================================================
FILE: Tone/component/channel/Recorder.test.ts
================================================
import { expect } from "chai";
import { connectFrom } from "../../../test/helper/Connect.js";
import { Context } from "../../core/context/Context.js";
import { ToneWithContext } from "../../core/context/ToneWithContext.js";
import { Synth } from "../../instrument/Synth.js";
import { Recorder } from "./Recorder.js";
describe("Recorder", () => {
context("basic", () => {
it("can be created and disposed", () => {
const rec = new Recorder();
rec.dispose();
});
it("handles input connections", () => {
const rec = new Recorder();
connectFrom().connect(rec);
rec.dispose();
});
it("reports if it is supported or not", () => {
expect(Recorder.supported).to.be.a("boolean");
});
it("can get the mime type", () => {
const rec = new Recorder();
expect(rec.mimeType).to.be.a("string");
rec.dispose();
});
it("can set a different context", () => {
const testContext = new Context();
const rec = new Recorder({
context: testContext,
});
for (const member in rec) {
if (rec[member] instanceof ToneWithContext) {
expect(rec[member].context, `member: ${member}`).to.equal(
testContext
);
}
}
testContext.dispose();
rec.dispose();
return testContext.close();
});
});
function wait(time) {
return new Promise((done) => setTimeout(done, time));
}
context("start/stop/pause", () => {
it("can be started", () => {
const rec = new Recorder();
rec.start();
expect(rec.state).to.equal("started");
rec.dispose();
});
it("can be paused after starting", async () => {
const rec = new Recorder();
rec.start();
expect(rec.state).to.equal("started");
await wait(100);
rec.pause();
expect(rec.state).to.equal("paused");
rec.dispose();
});
it("can be resumed after pausing", async () => {
const rec = new Recorder();
rec.start();
expect(rec.state).to.equal("started");
await wait(100);
rec.pause();
expect(rec.state).to.equal("paused");
await wait(100);
rec.start();
expect(rec.state).to.equal("started");
rec.dispose();
});
it("can be stopped after starting", async () => {
const rec = new Recorder();
rec.start();
expect(rec.state).to.equal("started");
await wait(100);
rec.stop();
expect(rec.state).to.equal("stopped");
rec.dispose();
});
it("throws an error if stopped or paused before starting", async () => {
const rec = new Recorder();
let didThrow = false;
try {
await rec.stop();
} catch (e) {
didThrow = true;
}
expect(didThrow).to.be.true;
expect(() => {
rec.pause();
}).to.throw(Error);
rec.dispose();
});
it("stop returns a blob", async () => {
const rec = new Recorder();
rec.start();
await wait(100);
const recording = await rec.stop();
expect(recording).to.be.instanceOf(Blob);
rec.dispose();
});
it("can record some sound", async () => {
const rec = new Recorder();
const synth = new Synth().connect(rec);
rec.start();
synth.triggerAttack("C3");
await wait(200);
const recording = await rec.stop();
expect(recording.size).to.be.greaterThan(0);
rec.dispose();
synth.dispose();
});
});
});
================================================
FILE: Tone/component/channel/Recorder.ts
================================================
import { theWindow } from "../../core/context/AudioContext.js";
import { Gain } from "../../core/context/Gain.js";
import {
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { assert } from "../../core/util/Debug.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { PlaybackState } from "../../core/util/StateTimeline.js";
export interface RecorderOptions extends ToneAudioNodeOptions {
mimeType?: string;
}
/**
* A wrapper around the MediaRecorder API. Unlike the rest of Tone.js, this module does not offer
* any sample-accurate scheduling because it is not a feature of the MediaRecorder API.
* This is only natively supported in Chrome and Firefox.
* For a cross-browser shim, install [audio-recorder-polyfill](https://www.npmjs.com/package/audio-recorder-polyfill).
* @example
* const recorder = new Tone.Recorder();
* const synth = new Tone.Synth().connect(recorder);
* // start recording
* recorder.start();
* // generate a few notes
* synth.triggerAttackRelease("C3", 0.5);
* synth.triggerAttackRelease("C4", 0.5, "+1");
* synth.triggerAttackRelease("C5", 0.5, "+2");
* // wait for the notes to end and stop the recording
* setTimeout(async () => {
* // the recorded audio is returned as a blob
* const recording = await recorder.stop();
* // download the recording by creating an anchor element and blob url
* const url = URL.createObjectURL(recording);
* const anchor = document.createElement("a");
* anchor.download = "recording.webm";
* anchor.href = url;
* anchor.click();
* }, 4000);
* @category Component
*/
export class Recorder extends ToneAudioNode<RecorderOptions> {
readonly name = "Recorder";
/**
* Recorder uses the Media Recorder API
*/
private _recorder: MediaRecorder;
/**
* MediaRecorder requires
*/
private _stream: MediaStreamAudioDestinationNode;
readonly input: Gain;
readonly output: undefined;
constructor(options?: Partial<RecorderOptions>);
constructor() {
const options = optionsFromArguments(Recorder.getDefaults(), arguments);
super(options);
this.input = new Gain({
context: this.context,
});
assert(Recorder.supported, "Media Recorder API is not available");
this._stream = this.context.createMediaStreamDestination();
this.input.connect(this._stream);
this._recorder = new MediaRecorder(this._stream.stream, {
mimeType: options.mimeType,
});
}
static getDefaults(): RecorderOptions {
return ToneAudioNode.getDefaults();
}
/**
* The mime type is the format that the audio is encoded in. For Chrome
* that is typically webm encoded as "vorbis".
*/
get mimeType(): string {
return this._recorder.mimeType;
}
/**
* Test if your platform supports the Media Recorder API. If it's not available,
* try installing this (polyfill)[https://www.npmjs.com/package/audio-recorder-polyfill].
*/
static get supported(): boolean {
return theWindow !== null && Reflect.has(theWindow, "MediaRecorder");
}
/**
* Get the playback state of the Recorder, either "started", "stopped" or "paused"
*/
get state(): PlaybackState {
if (this._recorder.state === "inactive") {
return "stopped";
} else if (this._recorder.state === "paused") {
return "paused";
} else {
return "started";
}
}
/**
* Start/Resume the Recorder. Returns a promise which resolves
* when the recorder has started.
*/
async start() {
assert(this.state !== "started", "Recorder is already started");
const startPromise = new Promise<void>((done) => {
const handleStart = () => {
this._recorder.removeEventListener("start", handleStart, false);
done();
};
this._recorder.addEventListener("start", handleStart, false);
});
if (this.state === "stopped") {
this._recorder.start();
} else {
this._recorder.resume();
}
return await startPromise;
}
/**
* Stop the recorder. Returns a promise with the recorded content until this point
* encoded as {@link mimeType}
*/
async stop(): Promise<Blob> {
assert(this.state !== "stopped", "Recorder is not started");
const dataPromise: Promise<Blob> = new Promise((done) => {
const handleData = (e: BlobEvent) => {
this._recorder.removeEventListener(
"dataavailable",
handleData,
false
);
done(e.data);
};
this._recorder.addEventListener("dataavailable", handleData, false);
});
this._recorder.stop();
return await dataPromise;
}
/**
* Pause the recorder
*/
pause(): this {
assert(this.state === "started", "Recorder must be started");
this._recorder.pause();
return this;
}
dispose(): this {
super.dispose();
this.input.dispose();
this._stream.disconnect();
return this;
}
}
================================================
FILE: Tone/component/channel/Solo.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { ConstantOutput } from "../../../test/helper/ConstantOutput.js";
import { Signal } from "../../signal/Signal.js";
import { Solo } from "./Solo.js";
describe("Solo", () => {
BasicTests(Solo);
context("Soloing", () => {
it("can be soloed an unsoloed", () => {
const sol = new Solo();
sol.solo = true;
expect(sol.solo).to.be.true;
sol.solo = false;
expect(sol.solo).to.be.false;
sol.dispose();
});
it("can be passed into the constructor", () => {
const sol = new Solo(true);
expect(sol.solo).to.be.true;
sol.dispose();
});
it("can be passed into the constructor with an object", () => {
const sol = new Solo({ solo: true });
expect(sol.solo).to.be.true;
sol.dispose();
});
it("other instances are unsoloed when one is soloed", () => {
const solA = new Solo();
const solB = new Solo();
solA.solo = true;
solB.solo = false;
expect(solA.solo).to.be.true;
expect(solB.solo).to.be.false;
solB.solo = true;
expect(solA.solo).to.be.true;
expect(solB.solo).to.be.true;
solA.solo = false;
expect(solA.solo).to.be.false;
expect(solB.solo).to.be.true;
solA.dispose();
solB.dispose();
});
it("other instances report themselves as muted", () => {
const solA = new Solo();
const solB = new Solo();
solA.solo = true;
solB.solo = false;
expect(solA.muted).to.be.false;
expect(solB.muted).to.be.true;
solA.dispose();
solB.dispose();
});
it("all instances are unmuted when there is no solo", () => {
const solA = new Solo();
const solB = new Solo();
solA.solo = true;
solB.solo = false;
solA.solo = false;
expect(solA.muted).to.be.false;
expect(solB.muted).to.be.false;
solA.dispose();
solB.dispose();
});
it("a newly created instance will be muted if there is already a soloed instance", () => {
const solA = new Solo(true);
const solB = new Solo();
expect(solA.muted).to.be.false;
expect(solB.muted).to.be.true;
solA.dispose();
solB.dispose();
});
it("passes both signals when nothing is soloed", () => {
return ConstantOutput(
() => {
const soloA = new Solo().toDestination();
const soloB = new Solo().toDestination();
new Signal(10).connect(soloA);
new Signal(20).connect(soloB);
},
30,
0.01
);
});
it("passes one signal when it is soloed", () => {
return ConstantOutput(
() => {
const soloA = new Solo().toDestination();
const soloB = new Solo().toDestination();
new Signal(10).connect(soloA);
new Signal(20).connect(soloB);
soloA.solo = true;
},
10,
0.01
);
});
it("can solo multiple at once", () => {
return ConstantOutput(
() => {
const soloA = new Solo().toDestination();
const soloB = new Solo().toDestination();
new Signal(10).connect(soloA);
new Signal(20).connect(soloB);
soloA.solo = true;
soloB.solo = true;
},
30,
0.01
);
});
it("can unsolo all", () => {
return ConstantOutput(
() => {
const soloA = new Solo().toDestination();
const soloB = new Solo().toDestination();
new Signal(10).connect(soloA);
new Signal(20).connect(soloB);
soloA.solo = true;
soloB.solo = true;
soloA.solo = false;
soloB.solo = false;
},
30,
0.01
);
});
it("can solo and unsolo while keeping previous soloed", () => {
return ConstantOutput(
() => {
const soloA = new Solo().toDestination();
const soloB = new Solo().toDestination();
new Signal(10).connect(soloA);
new Signal(20).connect(soloB);
soloA.solo = true;
soloB.solo = true;
soloB.solo = false;
},
10,
0.01
);
});
});
});
================================================
FILE: Tone/component/channel/Solo.ts
================================================
import { BaseContext } from "../../core/context/BaseContext.js";
import { Gain } from "../../core/context/Gain.js";
import {
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
export interface SoloOptions extends ToneAudioNodeOptions {
solo: boolean;
}
/**
* Solo lets you isolate a specific audio stream. When an instance is set to `solo=true`,
* it will mute all other instances of Solo.
* @example
* const soloA = new Tone.Solo().toDestination();
* const oscA = new Tone.Oscillator("C4", "sawtooth").connect(soloA);
* const soloB = new Tone.Solo().toDestination();
* const oscB = new Tone.Oscillator("E4", "square").connect(soloB);
* soloA.solo = true;
* // no audio will pass through soloB
* @category Component
*/
export class Solo extends ToneAudioNode<SoloOptions> {
readonly name: string = "Solo";
readonly input: Gain;
readonly output: Gain;
/**
* @param solo If the connection should be initially solo'ed.
*/
constructor(solo?: boolean);
constructor(options?: Partial<SoloOptions>);
constructor() {
const options = optionsFromArguments(Solo.getDefaults(), arguments, [
"solo",
]);
super(options);
this.input = this.output = new Gain({
context: this.context,
});
if (!Solo._allSolos.has(this.context)) {
Solo._allSolos.set(this.context, new Set());
}
(Solo._allSolos.get(this.context) as Set<Solo>).add(this);
// set initially
this.solo = options.solo;
}
static getDefaults(): SoloOptions {
return Object.assign(ToneAudioNode.getDefaults(), {
solo: false,
});
}
/**
* Hold all of the solo'ed tracks belonging to a specific context
*/
private static _allSolos: Map<BaseContext, Set<Solo>> = new Map();
/**
* Hold the currently solo'ed instance(s)
*/
private static _soloed: Map<BaseContext, Set<Solo>> = new Map();
/**
* Isolates this instance and mutes all other instances of Solo.
* Only one instance can be soloed at a time. A soloed
* instance will report `solo=false` when another instance is soloed.
*/
get solo(): boolean {
return this._isSoloed();
}
set solo(solo) {
if (solo) {
this._addSolo();
} else {
this._removeSolo();
}
(Solo._allSolos.get(this.context) as Set<Solo>).forEach((instance) =>
instance._updateSolo()
);
}
/**
* If the current instance is muted, i.e. another instance is soloed
*/
get muted(): boolean {
return this.input.gain.value === 0;
}
/**
* Add this to the soloed array
*/
private _addSolo(): void {
if (!Solo._soloed.has(this.context)) {
Solo._soloed.set(this.context, new Set());
}
(Solo._soloed.get(this.context) as Set<Solo>).add(this);
}
/**
* Remove this from the soloed array
*/
private _removeSolo(): void {
if (Solo._soloed.has(this.context)) {
(Solo._soloed.get(this.context) as Set<Solo>).delete(this);
}
}
/**
* Is this on the soloed array
*/
private _isSoloed(): boolean {
return (
Solo._soloed.has(this.context) &&
(Solo._soloed.get(this.context) as Set<Solo>).has(this)
);
}
/**
* Returns true if no one is soloed
*/
private _noSolos(): boolean {
// either does not have any soloed added
return (
!Solo._soloed.has(this.context) ||
// or has a solo set but doesn't include any items
(Solo._soloed.has(this.context) &&
(Solo._soloed.get(this.context) as Set<Solo>).size === 0)
);
}
/**
* Solo the current instance and unsolo all other instances.
*/
private _updateSolo(): void {
if (this._isSoloed()) {
this.input.gain.value = 1;
} else if (this._noSolos()) {
// no one is soloed
this.input.gain.value = 1;
} else {
this.input.gain.value = 0;
}
}
dispose(): this {
super.dispose();
(Solo._allSolos.get(this.context) as Set<Solo>).delete(this);
this._removeSolo();
return this;
}
}
================================================
FILE: Tone/component/channel/Split.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { connectTo } from "../../../test/helper/Connect.js";
import { ConstantOutput } from "../../../test/helper/ConstantOutput.js";
import { StereoSignal } from "../../../test/helper/StereoSignal.js";
import { Split } from "./Split.js";
describe("Split", () => {
BasicTests(Split);
context("Splitting", () => {
it("defaults to two channels", () => {
const split = new Split();
expect(split.numberOfOutputs).to.equal(2);
split.dispose();
});
it("can pass in more channels", () => {
const split = new Split(4);
expect(split.numberOfOutputs).to.equal(4);
split.connect(connectTo(), 0, 0);
split.connect(connectTo(), 1, 0);
split.connect(connectTo(), 2, 0);
split.connect(connectTo(), 3, 0);
split.dispose();
});
it("passes the incoming signal through on the left side", () => {
return ConstantOutput(({ destination }) => {
const split = new Split();
const signal = StereoSignal(1, 2).connect(split);
split.connect(destination, 0, 0);
}, 1);
});
it("passes the incoming signal through on the right side", () => {
return ConstantOutput(({ destination }) => {
const split = new Split();
const signal = StereoSignal(1, 2).connect(split);
split.connect(destination, 1, 0);
}, 2);
});
// it("merges two signal into one stereo signal and then split them back into two signals on left side", () => {
// return ConstantOutput(({destination}) => {
// const split = new Split();
// const signal = StereoSignal(1, 2).connect(split);
// split.connect(destination, 0, 0);
// }, 1);
// });
// it("merges two signal into one stereo signal and then split them back into two signals on right side", () => {
// return ConstantOutput(({destination}) => {
// const split = new Split();
// const signal = StereoSignal(1, 2).connect(split);
// split.connect(destination, 1, 0);
// }, 2);
// });
});
});
================================================
FILE: Tone/component/channel/Split.ts
================================================
import {
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
interface SplitOptions extends ToneAudioNodeOptions {
channels: number;
}
/**
* Split splits an incoming signal into the number of given channels.
*
* @example
* const split = new Tone.Split();
* // stereoSignal.connect(split);
* @category Component
*/
export class Split extends ToneAudioNode<SplitOptions> {
readonly name: string = "Split";
/**
* The splitting node
*/
private _splitter: ChannelSplitterNode;
readonly input: ChannelSplitterNode;
readonly output: ChannelSplitterNode;
/**
* @param channels The number of channels to merge.
*/
constructor(channels?: number);
constructor(options?: Partial<SplitOptions>);
constructor() {
const options = optionsFromArguments(Split.getDefaults(), arguments, [
"channels",
]);
super(options);
this._splitter =
this.input =
this.output =
this.context.createChannelSplitter(options.channels);
this._internalChannels = [this._splitter];
}
static getDefaults(): SplitOptions {
return Object.assign(ToneAudioNode.getDefaults(), {
channels: 2,
});
}
dispose(): this {
super.dispose();
this._splitter.disconnect();
return this;
}
}
================================================
FILE: Tone/component/channel/Volume.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { connectFrom, connectTo } from "../../../test/helper/Connect.js";
import { Offline } from "../../../test/helper/Offline.js";
import { PassAudio } from "../../../test/helper/PassAudio.js";
import { Signal } from "../../signal/Signal.js";
import { Volume } from "./Volume.js";
describe("Volume", () => {
BasicTests(Volume);
context("Volume", () => {
it("handles input and output connections", () => {
const vol = new Volume();
vol.connect(connectTo());
connectFrom().connect(vol);
connectFrom().connect(vol.volume);
vol.dispose();
});
it("can be constructed with volume value", () => {
const vol = new Volume(-12);
expect(vol.volume.value).to.be.closeTo(-12, 0.1);
vol.dispose();
});
it("can be constructed with an options object", () => {
const vol = new Volume({
volume: 2,
});
expect(vol.volume.value).to.be.closeTo(2, 0.1);
vol.dispose();
});
it("can be constructed with an options object and muted", () => {
const vol = new Volume({
mute: true,
});
expect(vol.mute).to.equal(true);
vol.dispose();
});
it("can set/get with an object", () => {
const vol = new Volume();
vol.set({
volume: -10,
});
expect(vol.get().volume).to.be.closeTo(-10, 0.1);
vol.dispose();
});
it("unmuting returns to previous volume", () => {
const vol = new Volume(-10);
vol.mute = true;
expect(vol.mute).to.equal(true);
expect(vol.volume.value).to.equal(-Infinity);
vol.mute = false;
// returns the volume to what it was
expect(vol.volume.value).to.be.closeTo(-10, 0.1);
vol.dispose();
});
it("passes the incoming signal through", () => {
return PassAudio((input) => {
const vol = new Volume().toDestination();
input.connect(vol);
});
});
it.skip("passes the incoming stereo signal through", () => {
// return PassAudioStereo(function(input) {
// const vol = new Volume().toDestination();
// input.connect(vol);
// });
});
it("can lower the volume", async () => {
const buffer = await Offline(() => {
const vol = new Volume(-10).toDestination();
new Signal(1).connect(vol);
});
expect(buffer.value()).to.be.closeTo(0.315, 0.01);
});
it("can mute the volume", async () => {
const buffer = await Offline(() => {
const vol = new Volume(0).toDestination();
new Signal(1).connect(vol);
vol.mute = true;
});
expect(buffer.isSilent()).to.equal(true);
});
it("muted when volume is set to -Infinity", async () => {
const buffer = await Offline(() => {
const vol = new Volume(-Infinity).toDestination();
new Signal(1).connect(vol);
expect(vol.mute).to.equal(true);
});
expect(buffer.isSilent()).to.equal(true);
});
it("setting the volume unmutes it and reports itself as unmuted", () => {
const vol = new Volume(0).toDestination();
vol.mute = true;
expect(vol.mute).to.equal(true);
vol.volume.value = 0;
expect(vol.mute).is.equal(false);
vol.dispose();
});
it("multiple calls to mute still return the vol to the original", () => {
const vol = new Volume(-20);
vol.mute = true;
vol.mute = true;
expect(vol.mute).to.equal(true);
expect(vol.volume.value).to.equal(-Infinity);
vol.mute = false;
vol.mute = false;
expect(vol.volume.value).to.be.closeTo(-20, 0.5);
vol.dispose();
});
});
});
================================================
FILE: Tone/component/channel/Volume.ts
================================================
import { Gain } from "../../core/context/Gain.js";
import { Param } from "../../core/context/Param.js";
import {
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { Decibels } from "../../core/type/Units.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { readOnly } from "../../core/util/Interface.js";
interface VolumeOptions extends ToneAudioNodeOptions {
volume: Decibels;
mute: boolean;
}
/**
* Volume is a simple volume node, useful for creating a volume fader.
*
* @example
* const vol = new Tone.Volume(-12).toDestination();
* const osc = new Tone.Oscillator().connect(vol).start();
* @category Component
*/
export class Volume extends ToneAudioNode<VolumeOptions> {
readonly name: string = "Volume";
/**
* the output node
*/
output: Gain<"decibels">;
/**
* Input and output are the same
*/
input: Gain<"decibels">;
/**
* The unmuted volume
*/
private _unmutedVolume: Decibels;
/**
* The volume control in decibels.
* @example
* const vol = new Tone.Volume().toDestination();
* const osc = new Tone.Oscillator().connect(vol).start();
* vol.volume.value = -20;
*/
volume: Param<"decibels">;
/**
* @param volume the initial volume in decibels
*/
constructor(volume?: Decibels);
constructor(options?: Partial<VolumeOptions>);
constructor() {
const options = optionsFromArguments(Volume.getDefaults(), arguments, [
"volume",
]);
super(options);
this.input = this.output = new Gain({
context: this.context,
gain: options.volume,
units: "decibels",
});
this.volume = this.output.gain;
readOnly(this, "volume");
this._unmutedVolume = options.volume;
// set the mute initially
this.mute = options.mute;
}
static getDefaults(): VolumeOptions {
return Object.assign(ToneAudioNode.getDefaults(), {
mute: false,
volume: 0,
});
}
/**
* Mute the output.
* @example
* const vol = new Tone.Volume(-12).toDestination();
* const osc = new Tone.Oscillator().connect(vol).start();
* // mute the output
* vol.mute = true;
*/
get mute(): boolean {
return this.volume.value === -Infinity;
}
set mute(mute: boolean) {
if (!this.mute && mute) {
this._unmutedVolume = this.volume.value;
// maybe it should ramp here?
this.volume.value = -Infinity;
} else if (this.mute && !mute) {
this.volume.value = this._unmutedVolume;
}
}
/**
* clean up
*/
dispose(): this {
super.dispose();
this.input.dispose();
this.volume.dispose();
return this;
}
}
================================================
FILE: Tone/component/dynamics/Compressor.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { PassAudio } from "../../../test/helper/PassAudio.js";
import { Compressor } from "./Compressor.js";
describe("Compressor", () => {
BasicTests(Compressor);
context("Compression", () => {
it("passes the incoming signal through", () => {
return PassAudio((input) => {
const comp = new Compressor().toDestination();
input.connect(comp);
});
});
it("can be get and set through object", () => {
const comp = new Compressor();
const values = {
attack: 0.03,
knee: 20,
ratio: 12,
release: 0.5,
threshold: -30,
};
comp.set(values);
expect(comp.get()).to.have.keys([
"ratio",
"threshold",
"release",
"attack",
"ratio",
]);
comp.dispose();
});
it("can be get and constructed with an object", () => {
const comp = new Compressor({
attack: 0.03,
knee: 20,
ratio: 12,
release: 0.5,
threshold: -30,
});
expect(comp.threshold.value).to.have.be.closeTo(-30, 1);
comp.dispose();
});
it("can be constructed with args", () => {
const comp = new Compressor(-10, 4);
expect(comp.threshold.value).to.have.be.closeTo(-10, 0.1);
expect(comp.ratio.value).to.have.be.closeTo(4, 0.1);
comp.dispose();
});
it("params have correct min and max values", () => {
const comp = new Compressor(-10, 4);
expect(comp.threshold.minValue).to.equal(-100);
expect(comp.threshold.maxValue).to.equal(0);
expect(comp.attack.minValue).to.equal(0);
expect(comp.attack.maxValue).to.equal(1);
expect(comp.release.minValue).to.equal(0);
expect(comp.release.maxValue).to.equal(1);
comp.dispose();
});
it("can get/set all interfaces", () => {
const comp = new Compressor();
const values = {
attack: 0.03,
knee: 18,
ratio: 12,
release: 0.5,
threshold: -30,
};
comp.ratio.value = values.ratio;
comp.threshold.value = values.threshold;
comp.release.value = values.release;
comp.attack.value = values.attack;
comp.knee.value = values.knee;
expect(comp.ratio.value).to.equal(values.ratio);
expect(comp.threshold.value).to.equal(values.threshold);
expect(comp.release.value).to.equal(values.release);
expect(comp.attack.value).to.be.closeTo(values.attack, 0.01);
expect(comp.knee.value).to.equal(values.knee);
comp.dispose();
});
});
});
================================================
FILE: Tone/component/dynamics/Compressor.ts
================================================
import { Param } from "../../core/context/Param.js";
import {
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { Decibels, Positive, Time } from "../../core/type/Units.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { readOnly } from "../../core/util/Interface.js";
export interface CompressorOptions extends ToneAudioNodeOptions {
attack: Time;
knee: Decibels;
ratio: Positive;
release: Time;
threshold: Decibels;
}
/**
* Compressor is a thin wrapper around the Web Audio
* [DynamicsCompressorNode](http://webaudio.github.io/web-audio-api/#the-dynamicscompressornode-interface).
* Compression reduces the volume of loud sounds or amplifies quiet sounds
* by narrowing or "compressing" an audio signal's dynamic range.
* Read more on [Wikipedia](https://en.wikipedia.org/wiki/Dynamic_range_compression).
* @example
* const comp = new Tone.Compressor(-30, 3);
* @category Component
*/
export class Compressor extends ToneAudioNode<CompressorOptions> {
readonly name: string = "Compressor";
/**
* the compressor node
*/
private _compressor: DynamicsCompressorNode =
this.context.createDynamicsCompressor();
readonly input = this._compressor;
readonly output = this._compressor;
/**
* The decibel value above which the compression will start taking effect.
* @min -100
* @max 0
*/
readonly threshold: Param<"decibels">;
/**
* The amount of time (in seconds) to reduce the gain by 10dB.
* @min 0
* @max 1
*/
readonly attack: Param<"time">;
/**
* The amount of time (in seconds) to increase the gain by 10dB.
* @min 0
* @max 1
*/
readonly release: Param<"time">;
/**
* A decibel value representing the range above the threshold where the
* curve smoothly transitions to the "ratio" portion.
* @min 0
* @max 40
*/
readonly knee: Param<"decibels">;
/**
* The amount of dB change in input for a 1 dB change in output.
* @min 1
* @max 20
*/
readonly ratio: Param<"positive">;
/**
* @param threshold The value above which the compression starts to be applied.
* @param ratio The gain reduction ratio.
*/
constructor(threshold?: Decibels, ratio?: Positive);
constructor(options?: Partial<CompressorOptions>);
constructor() {
const options = optionsFromArguments(
Compressor.getDefaults(),
arguments,
["threshold", "ratio"]
);
super(options);
this.threshold = new Param({
minValue: this._compressor.threshold.minValue,
maxValue: this._compressor.threshold.maxValue,
context: this.context,
convert: false,
param: this._compressor.threshold,
units: "decibels",
value: options.threshold,
});
this.attack = new Param({
minValue: this._compressor.attack.minValue,
maxValue: this._compressor.attack.maxValue,
context: this.context,
param: this._compressor.attack,
units: "time",
value: options.attack,
});
this.release = new Param({
minValue: this._compressor.release.minValue,
maxValue: this._compressor.release.maxValue,
context: this.context,
param: this._compressor.release,
units: "time",
value: options.release,
});
this.knee = new Param({
minValue: this._compressor.knee.minValue,
maxValue: this._compressor.knee.maxValue,
context: this.context,
convert: false,
param: this._compressor.knee,
units: "decibels",
value: options.knee,
});
this.ratio = new Param({
minValue: this._compressor.ratio.minValue,
maxValue: this._compressor.ratio.maxValue,
context: this.context,
convert: false,
param: this._compressor.ratio,
units: "positive",
value: options.ratio,
});
// set the defaults
readOnly(this, ["knee", "release", "attack", "ratio", "threshold"]);
}
static getDefaults(): CompressorOptions {
return Object.assign(ToneAudioNode.getDefaults(), {
attack: 0.003,
knee: 30,
ratio: 12,
release: 0.25,
threshold: -24,
});
}
/**
* A read-only decibel value for metering purposes, representing the current amount of gain
* reduction that the compressor is applying to the signal. If fed no signal the value will be 0 (no gain reduction).
*/
get reduction(): Decibels {
return this._compressor.reduction;
}
dispose(): this {
super.dispose();
this._compressor.disconnect();
this.attack.dispose();
this.release.dispose();
this.threshold.dispose();
this.ratio.dispose();
this.knee.dispose();
return this;
}
}
================================================
FILE: Tone/component/dynamics/Gate.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { CompareToFile } from "../../../test/helper/CompareToFile.js";
import { Offline } from "../../../test/helper/Offline.js";
import { Signal } from "../../signal/Signal.js";
import { Oscillator } from "../../source/oscillator/Oscillator.js";
import { Gate } from "./Gate.js";
describe("Gate", () => {
BasicTests(Gate);
it.only("matches a file", () => {
return CompareToFile(
() => {
const gate = new Gate(-10, 0.1).toDestination();
const osc = new Oscillator().connect(gate);
osc.start(0);
osc.volume.value = -100;
osc.volume.exponentialRampToValueAtTime(0, 0.5);
},
"gate.wav",
0.18
);
});
context("Signal Gating", () => {
it("handles getter/setter as Object", () => {
const gate = new Gate();
const values = {
smoothing: 0.2,
threshold: -20,
};
gate.set(values);
expect(gate.get().smoothing).to.be.closeTo(0.2, 0.001);
expect(gate.get().threshold).to.be.closeTo(-20, 0.1);
gate.dispose();
});
it("can be constructed with an object", () => {
const gate = new Gate({
smoothing: 0.3,
threshold: -5,
});
expect(gate.smoothing).to.be.closeTo(0.3, 0.001);
expect(gate.threshold).to.be.closeTo(-5, 0.1);
gate.dispose();
});
it("gates the incoming signal when below the threshold", async () => {
const buffer = await Offline(() => {
const gate = new Gate(-9);
const sig = new Signal(-12, "decibels");
sig.connect(gate);
gate.toDestination();
});
expect(buffer.isSilent()).to.be.true;
});
it("passes the incoming signal when above the threshold", async () => {
const buffer = await Offline(() => {
const gate = new Gate(-11);
const sig = new Signal(-10, "decibels");
sig.connect(gate);
gate.toDestination();
});
expect(buffer.min()).to.be.above(0);
});
});
});
================================================
FILE: Tone/component/dynamics/Gate.ts
================================================
import { Gain } from "../../core/context/Gain.js";
import {
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { dbToGain, gainToDb } from "../../core/type/Conversions.js";
import { Decibels, Time } from "../../core/type/Units.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { GreaterThan } from "../../signal/GreaterThan.js";
import { Follower } from "../analysis/Follower.js";
export interface GateOptions extends ToneAudioNodeOptions {
threshold: Decibels;
smoothing: Time;
}
/**
* Gate only passes a signal through when the incoming
* signal exceeds a specified threshold. It uses {@link Follower} to follow the ampltiude
* of the incoming signal and compares it to the {@link threshold} value using {@link GreaterThan}.
*
* @example
* const gate = new Tone.Gate(-30, 0.2).toDestination();
* const mic = new Tone.UserMedia().connect(gate);
* // the gate will only pass through the incoming
* // signal when it's louder than -30db
* @category Component
*/
export class Gate extends ToneAudioNode<GateOptions> {
readonly name: string = "Gate";
readonly input: ToneAudioNode;
readonly output: ToneAudioNode;
/**
* Follow the incoming signal
*/
private _follower: Follower;
/**
* Test if it's greater than the threshold
*/
private _gt: GreaterThan;
/**
* Gate the incoming signal when it does not exceed the threshold
*/
private _gate: Gain;
/**
* @param threshold The threshold above which the gate will open.
* @param smoothing The follower's smoothing time
*/
constructor(threshold?: Decibels, smoothing?: Time);
constructor(options?: Partial<GateOptions>);
constructor() {
const options = optionsFromArguments(Gate.getDefaults(), arguments, [
"threshold",
"smoothing",
]);
super(options);
this._follower = new Follower({
context: this.context,
smoothing: options.smoothing,
});
this._gt = new GreaterThan({
context: this.context,
value: dbToGain(options.threshold),
});
this.input = new Gain({ context: this.context });
this._gate = this.output = new Gain({ context: this.context });
// connections
this.input.connect(this._gate);
// the control signal
this.input.chain(this._follower, this._gt, this._gate.gain);
}
static getDefaults(): GateOptions {
return Object.assign(ToneAudioNode.getDefaults(), {
smoothing: 0.1,
threshold: -40,
});
}
/**
* The threshold of the gate in decibels
*/
get threshold(): Decibels {
return gainToDb(this._gt.value);
}
set threshold(thresh) {
this._gt.value = dbToGain(thresh);
}
/**
* The attack/decay speed of the gate.
* @see {@link Follower.smoothing}
*/
get smoothing(): Time {
return this._follower.smoothing;
}
set smoothing(smoothingTime) {
this._follower.smoothing = smoothingTime;
}
dispose(): this {
super.dispose();
this.input.dispose();
this._follower.dispose();
this._gt.dispose();
this._gate.dispose();
return this;
}
}
================================================
FILE: Tone/component/dynamics/Limiter.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { PassAudio } from "../../../test/helper/PassAudio.js";
import { Limiter } from "./Limiter.js";
describe("Limiter", () => {
BasicTests(Limiter);
context("Limiting", () => {
it("passes the incoming signal through", () => {
return PassAudio((input) => {
const limiter = new Limiter().toDestination();
input.connect(limiter);
});
});
it("can be get and set through object", () => {
const limiter = new Limiter();
const values = {
threshold: -30,
};
limiter.set(values);
expect(limiter.get().threshold).to.be.closeTo(-30, 0.1);
limiter.dispose();
});
it("can set the threshold", () => {
const limiter = new Limiter();
limiter.threshold.value = -10;
expect(limiter.threshold.value).to.be.closeTo(-10, 0.1);
limiter.dispose();
});
it("reduction is 0 when not connected", () => {
const limiter = new Limiter();
expect(limiter.reduction).to.be.closeTo(0, 0.01);
limiter.dispose();
});
});
});
================================================
FILE: Tone/component/dynamics/Limiter.ts
================================================
import { Param } from "../../core/context/Param.js";
import {
InputNode,
OutputNode,
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { Decibels } from "../../core/type/Units.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { readOnly } from "../../core/util/Interface.js";
import { Compressor } from "./Compressor.js";
export interface LimiterOptions extends ToneAudioNodeOptions {
threshold: Decibels;
}
/**
* Limiter will limit the loudness of an incoming signal.
* Under the hood its composed of a {@link Compressor} with a fast attack
* and release and max compression ratio.
*
* @example
* const limiter = new Tone.Limiter(-20).toDestination();
* const oscillator = new Tone.Oscillator().connect(limiter);
* oscillator.start();
* @category Component
*/
export class Limiter extends ToneAudioNode<LimiterOptions> {
readonly name: string = "Limiter";
readonly input: InputNode;
readonly output: OutputNode;
/**
* The compressor which does the limiting
*/
private _compressor: Compressor;
readonly threshold: Param<"decibels">;
/**
* @param threshold The threshold above which the gain reduction is applied.
*/
constructor(threshold?: Decibels);
constructor(options?: Partial<LimiterOptions>);
constructor() {
const options = optionsFromArguments(Limiter.getDefaults(), arguments, [
"threshold",
]);
super(options);
this._compressor =
this.input =
this.output =
new Compressor({
context: this.context,
ratio: 20,
attack: 0.003,
release: 0.01,
threshold: options.threshold,
});
this.threshold = this._compressor.threshold;
readOnly(this, "threshold");
}
static getDefaults(): LimiterOptions {
return Object.assign(ToneAudioNode.getDefaults(), {
threshold: -12,
});
}
/**
* A read-only decibel value for metering purposes, representing the current amount of gain
* reduction that the compressor is applying to the signal.
*/
get reduction(): Decibels {
return this._compressor.reduction;
}
dispose(): this {
super.dispose();
this._compressor.dispose();
this.threshold.dispose();
return this;
}
}
================================================
FILE: Tone/component/dynamics/MidSideCompressor.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { PassAudio } from "../../../test/helper/PassAudio.js";
import { MidSideCompressor } from "./MidSideCompressor.js";
describe("MidSideCompressor", () => {
BasicTests(MidSideCompressor);
context("Compression", () => {
it("passes the incoming signal through", () => {
return PassAudio((input) => {
const comp = new MidSideCompressor().toDestination();
input.connect(comp);
});
});
it("can be get and set through object", () => {
const comp = new MidSideCompressor();
const values = {
mid: {
ratio: 16,
threshold: -30,
},
side: {
release: 0.5,
attack: 0.03,
knee: 20,
},
};
comp.set(values);
expect(comp.get()).to.have.keys(["mid", "side"]);
expect(comp.get().mid.ratio).be.closeTo(16, 0.01);
expect(comp.get().side.release).be.closeTo(0.5, 0.01);
comp.dispose();
});
it("can be constructed with an options object", () => {
const comp = new MidSideCompressor({
mid: {
ratio: 16,
threshold: -30,
},
side: {
release: 0.5,
attack: 0.03,
knee: 20,
},
});
expect(comp.mid.ratio.value).be.closeTo(16, 0.01);
expect(comp.mid.threshold.value).be.closeTo(-30, 0.01);
expect(comp.side.release.value).be.closeTo(0.5, 0.01);
expect(comp.side.attack.value).be.closeTo(0.03, 0.01);
comp.dispose();
});
});
});
================================================
FILE: Tone/component/dynamics/MidSideCompressor.ts
================================================
import {
InputNode,
OutputNode,
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { readOnly, RecursivePartial } from "../../core/util/Interface.js";
import { MidSideMerge } from "../channel/MidSideMerge.js";
import { MidSideSplit } from "../channel/MidSideSplit.js";
import { Compressor, CompressorOptions } from "./Compressor.js";
export interface MidSideCompressorOptions extends ToneAudioNodeOptions {
mid: Omit<CompressorOptions, keyof ToneAudioNodeOptions>;
side: Omit<CompressorOptions, keyof ToneAudioNodeOptions>;
}
/**
* MidSideCompressor applies two different compressors to the {@link mid}
* and {@link side} signal components of the input.
* @see {@link MidSideSplit} and {@link MidSideMerge}.
* @category Component
*/
export class MidSideCompressor extends ToneAudioNode<MidSideCompressorOptions> {
readonly name: string = "MidSideCompressor";
readonly input: InputNode;
readonly output: OutputNode;
/**
* Split the incoming signal into Mid/Side
*/
private _midSideSplit: MidSideSplit;
/**
* Merge the compressed signal back into a single stream
*/
private _midSideMerge: MidSideMerge;
/**
* The compression applied to the mid signal
*/
readonly mid: Compressor;
/**
* The compression applied to the side signal
*/
readonly side: Compressor;
constructor(options?: RecursivePartial<MidSideCompressorOptions>);
constructor() {
const options = optionsFromArguments(
MidSideCompressor.getDefaults(),
arguments
);
super(options);
this._midSideSplit = this.input = new MidSideSplit({
context: this.context,
});
this._midSideMerge = this.output = new MidSideMerge({
context: this.context,
});
this.mid = new Compressor(
Object.assign(options.mid, { context: this.context })
);
this.side = new Compressor(
Object.assign(options.side, { context: this.context })
);
this._midSideSplit.mid.chain(this.mid, this._midSideMerge.mid);
this._midSideSplit.side.chain(this.side, this._midSideMerge.side);
readOnly(this, ["mid", "side"]);
}
static getDefaults(): MidSideCompressorOptions {
return Object.assign(ToneAudioNode.getDefaults(), {
mid: {
ratio: 3,
threshold: -24,
release: 0.03,
attack: 0.02,
knee: 16,
},
side: {
ratio: 6,
threshold: -30,
release: 0.25,
attack: 0.03,
knee: 10,
},
});
}
dispose(): this {
super.dispose();
this.mid.dispose();
this.side.dispose();
this._midSideSplit.dispose();
this._midSideMerge.dispose();
return this;
}
}
================================================
FILE: Tone/component/dynamics/MultibandCompressor.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { PassAudio } from "../../../test/helper/PassAudio.js";
import { MultibandCompressor } from "./MultibandCompressor.js";
describe("MultibandCompressor", () => {
BasicTests(MultibandCompressor);
context("Compression", () => {
it("passes the incoming signal through", () => {
return PassAudio((input) => {
const comp = new MultibandCompressor().toDestination();
input.connect(comp);
});
});
it("can be get and set through object", () => {
const comp = new MultibandCompressor();
const values = {
mid: {
ratio: 16,
threshold: -30,
},
high: {
release: 0.5,
attack: 0.03,
knee: 20,
},
};
comp.set(values);
expect(comp.get()).to.have.keys([
"low",
"mid",
"high",
"lowFrequency",
"highFrequency",
]);
expect(comp.get().mid.ratio).be.closeTo(16, 0.01);
expect(comp.get().high.release).be.closeTo(0.5, 0.01);
comp.dispose();
});
it("can be constructed with an options object", () => {
const comp = new MultibandCompressor({
mid: {
ratio: 16,
threshold: -30,
},
lowFrequency: 100,
});
expect(comp.mid.ratio.value).be.closeTo(16, 0.01);
expect(comp.mid.threshold.value).be.closeTo(-30, 0.01);
expect(comp.lowFrequency.value).be.closeTo(100, 0.01);
comp.dispose();
});
});
});
================================================
FILE: Tone/component/dynamics/MultibandCompressor.ts
================================================
import { Gain } from "../../core/context/Gain.js";
import {
InputNode,
ToneAudioNode,
ToneAudioNodeOptions,
} from "../../core/context/ToneAudioNode.js";
import { Frequency } from "../../core/type/Units.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { readOnly, RecursivePartial } from "../../core/util/Interface.js";
import { Signal } from "../../signal/Signal.js";
import { MultibandSplit } from "../channel/MultibandSplit.js";
import { Compressor, CompressorOptions } from "./Compressor.js";
export interface MultibandCompressorOptions extends ToneAudioNodeOptions {
mid: Omit<CompressorOptions, keyof ToneAudioNodeOptions>;
low: Omit<CompressorOptions, keyof ToneAudioNodeOptions>;
high: Omit<CompressorOptions, keyof ToneAudioNodeOptions>;
lowFrequency: Frequency;
highFrequency: Frequency;
}
/**
* A compressor with separate controls over low/mid/high dynamics.
* @see {@link Compressor} and {@link MultibandSplit}
*
* @example
* const multiband = new Tone.MultibandCompressor({
* lowFrequency: 200,
* highFrequency: 1300,
* low: {
* threshold: -12
* }
* });
* @category Component
*/
export class MultibandCompressor extends ToneAudioNode<MultibandCompressorOptions> {
readonly name: string = "MultibandCompressor";
readonly input: InputNode;
readonly output: ToneAudioNode;
/**
* Split the incoming signal into high/mid/low
*/
private _splitter: MultibandSplit;
/**
* low/mid crossover frequency.
*/
readonly lowFrequency: Signal<"frequency">;
/**
* mid/high crossover frequency.
*/
readonly highFrequency: Signal<"frequency">;
/**
* The compressor applied to the low frequencies
*/
readonly low: Compressor;
/**
* The compressor applied to the mid frequencies
*/
readonly mid: Compressor;
/**
* The compressor applied to the high frequencies
*/
readonly high: Compressor;
constructor(options?: RecursivePartial<MultibandCompressorOptions>);
constructor() {
const options = optionsFromArguments(
MultibandCompressor.getDefaults(),
arguments
);
super(options);
this._splitter = this.input = new MultibandSplit({
context: this.context,
lowFrequency: options.lowFrequency,
highFrequency: options.highFrequency,
});
this.lowFrequency = this._splitter.lowFrequency;
this.highFrequency = this._splitter.highFrequency;
this.output = new Gain({ context: this.context });
this.low = new Compressor(
Object.assign(options.low, { context: this.context })
);
this.mid = new Compressor(
Object.assign(options.mid, { context: this.context })
);
this.high = new Compressor(
Object.assign(options.high, { context: this.context })
);
// connect the compressor
this._splitter.low.chain(this.low, this.output);
this._splitter.mid.chain(this.mid, this.output);
this._splitter.high.chain(this.high, this.output);
readOnly(this, ["high", "mid", "low", "highFrequency", "lowFrequency"]);
}
static getDefaults(): MultibandCompressorOptions {
return Object.assign(ToneAudioNode.getDefaults(), {
lowFrequency: 250,
highFrequency: 2000,
low: {
ratio: 6,
threshold: -30,
release: 0.25,
attack: 0.03,
knee: 10,
},
mid: {
ratio: 3,
threshold: -24,
release: 0.03,
attack: 0.02,
knee: 16,
},
high: {
ratio: 3,
threshold: -24,
release: 0.03,
attack: 0.02,
knee: 16,
},
});
}
dispose(): this {
super.dispose();
this._splitter.dispose();
this.low.dispose();
this.mid.dispose();
this.high.dispose();
this.output.dispose();
return this;
}
}
================================================
FILE: Tone/component/envelope/AmplitudeEnvelope.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { CompareToFile } from "../../../test/helper/CompareToFile.js";
import { Offline } from "../../../test/helper/Offline.js";
import { Signal } from "../../signal/Signal.js";
import { Oscillator } from "../../source/oscillator/Oscillator.js";
import { AmplitudeEnvelope } from "./AmplitudeEnvelope.js";
import { Envelope } from "./Envelope.js";
describe("AmplitudeEnvelope", () => {
BasicTests(AmplitudeEnvelope);
context("Comparisons", () => {
it("matches a file", () => {
return CompareToFile(() => {
const ampEnv = new AmplitudeEnvelope({
attack: 0.1,
decay: 0.2,
release: 0.2,
sustain: 0.1,
}).toDestination();
const osc = new Oscillator().start(0).connect(ampEnv);
ampEnv.triggerAttack(0);
ampEnv.triggerRelease(0.3);
}, "ampEnvelope.wav");
});
it("matches a file with multiple retriggers", () => {
return CompareToFile(
() => {
const ampEnv = new AmplitudeEnvelope({
attack: 0.1,
decay: 0.2,
release: 0.2,
sustain: 0.1,
}).toDestination();
const osc = new Oscillator().start(0).connect(ampEnv);
ampEnv.triggerAttack(0);
ampEnv.triggerAttack(0.3);
},
"ampEnvelope2.wav",
0.004
);
});
it("matches a file with ripple attack/release", () => {
return CompareToFile(
() => {
const ampEnv = new AmplitudeEnvelope({
attack: 0.5,
attackCurve: "ripple",
decay: 0.2,
release: 0.3,
releaseCurve: "ripple",
sustain: 0.1,
}).toDestination();
const osc = new Oscillator().start(0).connect(ampEnv);
ampEnv.triggerAttack(0);
ampEnv.triggerRelease(0.7);
ampEnv.triggerAttack(1);
ampEnv.triggerRelease(1.6);
},
"ampEnvelope3.wav",
0.002
);
});
});
context("Envelope", () => {
it("extends envelope", () => {
const ampEnv = new AmplitudeEnvelope();
expect(ampEnv).to.be.instanceOf(Envelope);
ampEnv.dispose();
});
it("passes no signal before being triggered", async () => {
const buffer = await Offline(() => {
const ampEnv = new AmplitudeEnvelope().toDestination();
new Signal(1).connect(ampEnv);
});
expect(buffer.isSilent()).to.be.true;
});
it("passes signal once triggered", async () => {
const buffer = await Offline(() => {
const ampEnv = new AmplitudeEnvelope().toDestination();
new Signal(1).connect(ampEnv);
ampEnv.triggerAttack(0.1);
}, 0.2);
expect(buffer.getTimeOfFirstSound()).to.be.closeTo(0.1, 0.001);
});
});
});
================================================
FILE: Tone/component/envelope/AmplitudeEnvelope.ts
================================================
import { Gain } from "../../core/context/Gain.js";
import { NormalRange, Time } from "../../core/type/Units.js";
import { optionsFromArguments } from "../../core/util/Defaults.js";
import { Envelope, EnvelopeOptions } from "./Envelope.js";
/**
* AmplitudeEnvelope is a Tone.Envelope connected to a gain node.
* Unlike Tone.Envelope, which outputs the envelope's value, AmplitudeEnvelope accepts
* an audio signal as the input and will apply the envelope to the amplitude
* of the signal.
* Read more about ADSR Envelopes on [Wikipedia](https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope).
*
* @example
* return Tone.Offline(() => {
* const ampEnv = new Tone.AmplitudeEnvelope({
* attack: 0.1,
* decay: 0.2,
* sustain: 1.0,
* release: 0.8
* }).toDestination();
* // create an oscillator and connect it
* const osc = new Tone.Oscillator().connect(ampEnv).start();
* // trigger the envelopes attack and release "8t" apart
* ampEnv.triggerAttackRelease("8t");
* }, 1.5, 1);
* @category Component
*/
export class AmplitudeEnvelope extends Envelope {
readonly name: string = "AmplitudeEnvelope";
private _gainNode: Gain = new Gain({
context: this.context,
gain: 0,
});
output: Gain = this._gainNode;
input: Gain = this._gainNode;
/**
* @param attack The amount of time it takes for the envelope to go from 0 to its maximum value.
* @param decay The period of time after the attack that it takes for the envelope
* to fall to the sustain value. Value must be greater than 0.
* @param sustain The percent of the maximum value that the envelope rests at until
* the release is triggered.
* @param release The amount of time after the release is triggered it takes to reach 0.
* Value must be greater than 0.
*/
constructor(
attack?: Time,
decay?: Time,
sustain?: NormalRange,
release?: Time
);
constructor(options?: Partial<EnvelopeOptions>);
constructor() {
super(
optionsFromArguments(AmplitudeEnvelope.getDefaults(), arguments, [
"attack",
"decay",
"sustain",
"release",
])
);
this._sig.connect(this._gainNode.gain);
this.output = this._gainNode;
this.input = this._gainNode;
}
/**
* Clean up
*/
dispose(): this {
super.dispose();
this._gainNode.dispose();
return this;
}
}
================================================
FILE: Tone/component/envelope/Envelope.test.ts
================================================
import { expect } from "chai";
import { BasicTests } from "../../../test/helper/Basic.js";
import { connectTo } from "../../../test/helper/Connect.js";
import { Offline } from "../../../test/helper/Offline.js";
import { SignalConnectAndDisconnect } from "../../../test/helper/SignalTests.js";
import { Envelope, EnvelopeCurve } from "./Envelope.js";
describe("Envelope", () => {
BasicTests(Envelope);
SignalConnectAndDisconnect(Envelope);
context("Envelope", () => {
it("has an output connections", () => {
const env = new Envelope();
env.connect(connectTo());
env.dispose();
});
it("can get and set values an Objects", () => {
const env = new Envelope();
const values = {
attack: 0,
decay: 0.5,
release: "4n",
sustain: 1,
};
env.set(values);
expect(env.get()).to.contain.keys(Object.keys(values));
env.dispose();
});
it("passes no signal before being triggered", async () => {
const buffer = await Offline(() => {
new Envelope().toDestination();
});
expect(buffer.isSilent()).to.equal(true);
});
it("passes signal once triggered", async () => {
const buffer = await Offline(() => {
const env = new Envelope().toDestination();
env.triggerAttack(0.05);
}, 0.1);
expect(buffer.getTimeOfFirstSound()).to.be.closeTo(0.05, 0.001);
});
it("can take parameters as both an object and as arguments", () => {
const env0 = new Envelope({
attack: 0,
decay: 0.5,
sustain: 1,
});
expect(env0.attack).to.equal(0);
expect(env0.decay).to.equal(0.5);
expect(env0.sustain).to.equal(1);
env0.dispose();
const env1 = new Envelope(0.1, 0.2, 0.3);
expect(env1.attack).to.equal(0.1);
expect(env1.decay).to.equal(0.2);
expect(env1.sustain).to.equal(0.3);
env1.dispose();
});
it("ensures that none of the values go below 0", () => {
const env = new Envelope();
expect(() => {
env.attack = -1;
}).to.throw(RangeError);
expect(() => {
env.decay = -1;
}).to.throw(RangeError);
expect(() => {
env.sustain = 2;
}).to.throw(RangeError);
expect(() => {
env.release = -1;
}).to.throw(RangeError);
env.dispose();
});
it("can set attack to exponential or linear", () => {
const env = new Envelope(0.01, 0.01, 0.5, 0.3);
env.attackCurve = "exponential";
expect(env.attackCurve).to.equal("exponential");
env.triggerAttack();
env.dispose();
// and can be linear
const env2 = new Envelope(0.01, 0.01, 0.5, 0.3);
env2.attackCurve = "linear";
expect(env2.attackCurve).to.equal("linear");
env2.triggerAttack();
// and test a non-curve
expect(() => {
// @ts-ignore
env2.attackCurve = "other";
}).to.throw(Error);
env2.dispose();
});
it("can set decay to exponential or linear", () => {
const env = new Envelope(0.01, 0.01, 0.5, 0.3);
env.decayCurve = "exponential";
expect(env.decayCurve).to.equal("exponential");
env.triggerAttack();
env.dispose();
// and can be linear
const env2 = new Envelope(0.01, 0.01, 0.5, 0.3);
env2.decayCurve = "linear";
expect(env2.decayCurve).to.equal("linear");
env2.triggerAttack();
// and test a non-curve
expect(() => {
// @ts-ignore
env2.decayCurve = "other";
}).to.throw(Error);
env2.dispose();
});
it("can set release to exponential or linear", () => {
const env = new Envelope(0.01, 0.01, 0.5, 0.3);
env.releaseCurve = "exponential";
expect(env.releaseCurve).to.equal("exponential");
env.triggerRelease();
env.dispose();
// and can be linear
const env2 = new Envelope(0.01, 0.01, 0.5, 0.3);
env2.releaseCurve = "linear";
expect(env2.releaseCurve).to.equal("linear");
env2.triggerRelease();
// and test a non-curve
expect(() => {
// @ts-ignore
env2.releaseCurve = "other";
}).to.throw(Error);
env2.dispose();
});
it("can set release to exponential or linear", async () => {
const buffer = await Offline(() => {
const env = new Envelope({
release: 0,
});
env.toDestination();
env.triggerAttackRelease(0.4, 0);
}, 0.7);
expect(buffer.getValueAtTime(0.3)).to.be.above(0);
expect(buffer.getValueAtTime(0.401)).to.equal(0);
});
it("schedule a release at the moment when the attack portion is done", async () => {
const buffer = await Offline(() => {
const env = new Envelope({
attack: 0.5,
decay: 0.0,
sustain: 1,
release: 0.5,
}).toDestination();
env.triggerAttackRelease(0.5);
}, 0.7);
// make sure that it's got the rising edge
expect(buffer.getValueAtTime(0.1)).to.be.closeTo(0.2, 0.01);
expect(buffer.getValueAtTime(0.2)).to.be.closeTo(0.4, 0.01);
expect(buffer.getValueAtTime(0.3)).to.be.closeTo(0.6, 0.01);
expect(buffer.getValueAtTime(0.4)).to.be.closeTo(0.8, 0.01);
expect(buffer.getValueAtTime(0.5)).to.be.be.closeTo(1, 0.001);
});
it("correctly schedules an exponential attack",
gitextract_3dx9qg9q/ ├── .github/ │ ├── CONTRIBUTING.md │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ └── feature_request.md │ ├── PULL_REQUEST_TEMPLATE.md │ ├── codecov.yml │ └── workflows/ │ ├── stale.yml │ └── test.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── Tone/ │ ├── classes.ts │ ├── component/ │ │ ├── analysis/ │ │ │ ├── Analyser.test.ts │ │ │ ├── Analyser.ts │ │ │ ├── DCMeter.test.ts │ │ │ ├── DCMeter.ts │ │ │ ├── FFT.test.ts │ │ │ ├── FFT.ts │ │ │ ├── Follower.test.ts │ │ │ ├── Follower.ts │ │ │ ├── Meter.test.ts │ │ │ ├── Meter.ts │ │ │ ├── MeterBase.ts │ │ │ ├── Waveform.test.ts │ │ │ └── Waveform.ts │ │ ├── channel/ │ │ │ ├── Channel.test.ts │ │ │ ├── Channel.ts │ │ │ ├── CrossFade.test.ts │ │ │ ├── CrossFade.ts │ │ │ ├── Merge.test.ts │ │ │ ├── Merge.ts │ │ │ ├── MidSideMerge.test.ts │ │ │ ├── MidSideMerge.ts │ │ │ ├── MidSideSplit.test.ts │ │ │ ├── MidSideSplit.ts │ │ │ ├── Mono.test.ts │ │ │ ├── Mono.ts │ │ │ ├── MultibandSplit.test.ts │ │ │ ├── MultibandSplit.ts │ │ │ ├── PanVol.test.ts │ │ │ ├── PanVol.ts │ │ │ ├── Panner.test.ts │ │ │ ├── Panner.ts │ │ │ ├── Panner3D.test.ts │ │ │ ├── Panner3D.ts │ │ │ ├── Recorder.test.ts │ │ │ ├── Recorder.ts │ │ │ ├── Solo.test.ts │ │ │ ├── Solo.ts │ │ │ ├── Split.test.ts │ │ │ ├── Split.ts │ │ │ ├── Volume.test.ts │ │ │ └── Volume.ts │ │ ├── dynamics/ │ │ │ ├── Compressor.test.ts │ │ │ ├── Compressor.ts │ │ │ ├── Gate.test.ts │ │ │ ├── Gate.ts │ │ │ ├── Limiter.test.ts │ │ │ ├── Limiter.ts │ │ │ ├── MidSideCompressor.test.ts │ │ │ ├── MidSideCompressor.ts │ │ │ ├── MultibandCompressor.test.ts │ │ │ └── MultibandCompressor.ts │ │ ├── envelope/ │ │ │ ├── AmplitudeEnvelope.test.ts │ │ │ ├── AmplitudeEnvelope.ts │ │ │ ├── Envelope.test.ts │ │ │ ├── Envelope.ts │ │ │ ├── FrequencyEnvelope.test.ts │ │ │ └── FrequencyEnvelope.ts │ │ ├── filter/ │ │ │ ├── BiquadFilter.test.ts │ │ │ ├── BiquadFilter.ts │ │ │ ├── Convolver.test.ts │ │ │ ├── Convolver.ts │ │ │ ├── EQ3.test.ts │ │ │ ├── EQ3.ts │ │ │ ├── FeedbackCombFilter.test.ts │ │ │ ├── FeedbackCombFilter.ts │ │ │ ├── FeedbackCombFilter.worklet.ts │ │ │ ├── Filter.test.ts │ │ │ ├── Filter.ts │ │ │ ├── LowpassCombFilter.test.ts │ │ │ ├── LowpassCombFilter.ts │ │ │ ├── OnePoleFilter.test.ts │ │ │ ├── OnePoleFilter.ts │ │ │ ├── PhaseShiftAllpass.test.ts │ │ │ └── PhaseShiftAllpass.ts │ │ └── index.ts │ ├── core/ │ │ ├── Global.ts │ │ ├── Tone.ts │ │ ├── clock/ │ │ │ ├── Clock.test.ts │ │ │ ├── Clock.ts │ │ │ ├── TickParam.test.ts │ │ │ ├── TickParam.ts │ │ │ ├── TickSignal.test.ts │ │ │ ├── TickSignal.ts │ │ │ ├── TickSource.test.ts │ │ │ ├── TickSource.ts │ │ │ ├── Ticker.test.ts │ │ │ ├── Ticker.ts │ │ │ ├── Transport.test.ts │ │ │ ├── Transport.ts │ │ │ ├── TransportEvent.test.ts │ │ │ ├── TransportEvent.ts │ │ │ ├── TransportRepeatEvent.test.ts │ │ │ └── TransportRepeatEvent.ts │ │ ├── context/ │ │ │ ├── AbstractParam.ts │ │ │ ├── AudioContext.ts │ │ │ ├── BaseContext.ts │ │ │ ├── Context.test.ts │ │ │ ├── Context.ts │ │ │ ├── ContextInitialization.ts │ │ │ ├── Delay.test.ts │ │ │ ├── Delay.ts │ │ │ ├── Destination.test.ts │ │ │ ├── Destination.ts │ │ │ ├── DummyContext.test.ts │ │ │ ├── DummyContext.ts │ │ │ ├── Gain.test.ts │ │ │ ├── Gain.ts │ │ │ ├── Listener.test.ts │ │ │ ├── Listener.ts │ │ │ ├── Offline.test.ts │ │ │ ├── Offline.ts │ │ │ ├── OfflineContext.test.ts │ │ │ ├── OfflineContext.ts │ │ │ ├── OnRunning.test.ts │ │ │ ├── OnRunning.ts │ │ │ ├── Param.test.ts │ │ │ ├── Param.ts │ │ │ ├── ToneAudioBuffer.test.ts │ │ │ ├── ToneAudioBuffer.ts │ │ │ ├── ToneAudioBuffers.test.ts │ │ │ ├── ToneAudioBuffers.ts │ │ │ ├── ToneAudioNode.test.ts │ │ │ ├── ToneAudioNode.ts │ │ │ ├── ToneWithContext.test.ts │ │ │ └── ToneWithContext.ts │ │ ├── index.ts │ │ ├── type/ │ │ │ ├── Conversions.test.ts │ │ │ ├── Conversions.ts │ │ │ ├── Frequency.test.ts │ │ │ ├── Frequency.ts │ │ │ ├── Midi.test.ts │ │ │ ├── Midi.ts │ │ │ ├── NoteUnits.ts │ │ │ ├── Ticks.test.ts │ │ │ ├── Ticks.ts │ │ │ ├── Time.test.ts │ │ │ ├── Time.ts │ │ │ ├── TimeBase.ts │ │ │ ├── TransportTime.test.ts │ │ │ ├── TransportTime.ts │ │ │ └── Units.ts │ │ ├── util/ │ │ │ ├── AdvancedTypeCheck.ts │ │ │ ├── Debug.test.ts │ │ │ ├── Debug.ts │ │ │ ├── Decorator.ts │ │ │ ├── Defaults.ts │ │ │ ├── Draw.test.ts │ │ │ ├── Draw.ts │ │ │ ├── Emitter.test.ts │ │ │ ├── Emitter.ts │ │ │ ├── Interface.ts │ │ │ ├── IntervalTimeline.test.ts │ │ │ ├── IntervalTimeline.ts │ │ │ ├── Math.ts │ │ │ ├── StateTimeline.test.ts │ │ │ ├── StateTimeline.ts │ │ │ ├── Timeline.test.ts │ │ │ ├── Timeline.ts │ │ │ ├── TimelineValue.test.ts │ │ │ ├── TimelineValue.ts │ │ │ ├── TypeCheck.ts │ │ │ └── global.d.ts │ │ └── worklet/ │ │ ├── DelayLine.worklet.ts │ │ ├── SingleIOProcessor.worklet.ts │ │ ├── ToneAudioWorklet.ts │ │ ├── ToneAudioWorkletProcessor.worklet.ts │ │ └── WorkletGlobalScope.ts │ ├── effect/ │ │ ├── AutoFilter.test.ts │ │ ├── AutoFilter.ts │ │ ├── AutoPanner.test.ts │ │ ├── AutoPanner.ts │ │ ├── AutoWah.test.ts │ │ ├── AutoWah.ts │ │ ├── BitCrusher.test.ts │ │ ├── BitCrusher.ts │ │ ├── BitCrusher.worklet.ts │ │ ├── Chebyshev.test.ts │ │ ├── Chebyshev.ts │ │ ├── Chorus.test.ts │ │ ├── Chorus.ts │ │ ├── Distortion.test.ts │ │ ├── Distortion.ts │ │ ├── Effect.ts │ │ ├── FeedbackDelay.test.ts │ │ ├── FeedbackDelay.ts │ │ ├── FeedbackEffect.ts │ │ ├── Freeverb.test.ts │ │ ├── Freeverb.ts │ │ ├── FrequencyShifter.test.ts │ │ ├── FrequencyShifter.ts │ │ ├── JCReverb.test.ts │ │ ├── JCReverb.ts │ │ ├── LFOEffect.ts │ │ ├── LFOStereoEffect.test.ts │ │ ├── LFOStereoEffect.ts │ │ ├── MidSideEffect.ts │ │ ├── Phaser.test.ts │ │ ├── Phaser.ts │ │ ├── PingPongDelay.test.ts │ │ ├── PingPongDelay.ts │ │ ├── PitchShift.test.ts │ │ ├── PitchShift.ts │ │ ├── Reverb.test.ts │ │ ├── Reverb.ts │ │ ├── ReverseDelay.test.ts │ │ ├── ReverseDelay.ts │ │ ├── ReverseDelay.worklet.ts │ │ ├── StereoEffect.ts │ │ ├── StereoFeedbackEffect.ts │ │ ├── StereoWidener.test.ts │ │ ├── StereoWidener.ts │ │ ├── StereoXFeedbackEffect.ts │ │ ├── Tremolo.test.ts │ │ ├── Tremolo.ts │ │ ├── Vibrato.test.ts │ │ ├── Vibrato.ts │ │ └── index.ts │ ├── event/ │ │ ├── Loop.test.ts │ │ ├── Loop.ts │ │ ├── Part.test.ts │ │ ├── Part.ts │ │ ├── Pattern.test.ts │ │ ├── Pattern.ts │ │ ├── PatternGenerator.test.ts │ │ ├── PatternGenerator.ts │ │ ├── Sequence.test.ts │ │ ├── Sequence.ts │ │ ├── ToneEvent.test.ts │ │ ├── ToneEvent.ts │ │ └── index.ts │ ├── fromContext.test.ts │ ├── fromContext.ts │ ├── index.test.ts │ ├── index.ts │ ├── instrument/ │ │ ├── AMSynth.test.ts │ │ ├── AMSynth.ts │ │ ├── DuoSynth.test.ts │ │ ├── DuoSynth.ts │ │ ├── FMSynth.test.ts │ │ ├── FMSynth.ts │ │ ├── Instrument.ts │ │ ├── MembraneSynth.test.ts │ │ ├── MembraneSynth.ts │ │ ├── MetalSynth.test.ts │ │ ├── MetalSynth.ts │ │ ├── ModulationSynth.ts │ │ ├── MonoSynth.test.ts │ │ ├── MonoSynth.ts │ │ ├── Monophonic.ts │ │ ├── NoiseSynth.test.ts │ │ ├── NoiseSynth.ts │ │ ├── PluckSynth.test.ts │ │ ├── PluckSynth.ts │ │ ├── PolySynth.test.ts │ │ ├── PolySynth.ts │ │ ├── Sampler.test.ts │ │ ├── Sampler.ts │ │ ├── Synth.test.ts │ │ ├── Synth.ts │ │ └── index.ts │ ├── signal/ │ │ ├── Abs.test.ts │ │ ├── Abs.ts │ │ ├── Add.test.ts │ │ ├── Add.ts │ │ ├── AudioToGain.test.ts │ │ ├── AudioToGain.ts │ │ ├── GainToAudio.test.ts │ │ ├── GainToAudio.ts │ │ ├── GreaterThan.test.ts │ │ ├── GreaterThan.ts │ │ ├── GreaterThanZero.test.ts │ │ ├── GreaterThanZero.ts │ │ ├── Multiply.test.ts │ │ ├── Multiply.ts │ │ ├── Negate.test.ts │ │ ├── Negate.ts │ │ ├── Pow.test.ts │ │ ├── Pow.ts │ │ ├── Scale.test.ts │ │ ├── Scale.ts │ │ ├── ScaleExp.test.ts │ │ ├── ScaleExp.ts │ │ ├── Signal.test.ts │ │ ├── Signal.ts │ │ ├── SignalOperator.test.ts │ │ ├── SignalOperator.ts │ │ ├── Subtract.test.ts │ │ ├── Subtract.ts │ │ ├── SyncedSignal.test.ts │ │ ├── SyncedSignal.ts │ │ ├── ToneConstantSource.test.ts │ │ ├── ToneConstantSource.ts │ │ ├── WaveShaper.test.ts │ │ ├── WaveShaper.ts │ │ ├── Zero.test.ts │ │ ├── Zero.ts │ │ └── index.ts │ └── source/ │ ├── Noise.test.ts │ ├── Noise.ts │ ├── OneShotSource.ts │ ├── Source.test.ts │ ├── Source.ts │ ├── UserMedia.test.ts │ ├── UserMedia.ts │ ├── buffer/ │ │ ├── GrainPlayer.test.ts │ │ ├── GrainPlayer.ts │ │ ├── Player.test.ts │ │ ├── Player.ts │ │ ├── Players.test.ts │ │ ├── Players.ts │ │ ├── ToneBufferSource.test.ts │ │ └── ToneBufferSource.ts │ ├── index.ts │ └── oscillator/ │ ├── AMOscillator.test.ts │ ├── AMOscillator.ts │ ├── FMOscillator.test.ts │ ├── FMOscillator.ts │ ├── FatOscillator.test.ts │ ├── FatOscillator.ts │ ├── LFO.test.ts │ ├── LFO.ts │ ├── OmniOscillator.test.ts │ ├── OmniOscillator.ts │ ├── Oscillator.test.ts │ ├── Oscillator.ts │ ├── OscillatorInterface.ts │ ├── PWMOscillator.test.ts │ ├── PWMOscillator.ts │ ├── PulseOscillator.test.ts │ ├── PulseOscillator.ts │ ├── ToneOscillatorNode.test.ts │ └── ToneOscillatorNode.ts ├── eslint.config.mjs ├── examples/ │ ├── README.md │ ├── amSynth.html │ ├── analysis.html │ ├── animationSync.html │ ├── bembe.html │ ├── buses.html │ ├── daw.html │ ├── envelope.html │ ├── events.html │ ├── fmSynth.html │ ├── funkyShape.html │ ├── grainPlayer.html │ ├── index.html │ ├── js/ │ │ ├── ExampleList.json │ │ ├── components.js │ │ └── tone-ui.js │ ├── jump.html │ ├── lfoEffects.html │ ├── meter.html │ ├── mic.html │ ├── mixer.html │ ├── monoSynth.html │ ├── noises.html │ ├── offline.html │ ├── oscillator.html │ ├── pianoPhase.html │ ├── pingPongDelay.html │ ├── pitchShift.html │ ├── player.html │ ├── polySynth.html │ ├── quantization.html │ ├── rampTo.html │ ├── reverb.html │ ├── reverseDelay.html │ ├── sampler.html │ ├── shiny.html │ ├── signal.html │ ├── simpleHtml.html │ ├── simpleSynth.html │ ├── spatialPanner.html │ └── stepSequencer.html ├── package.json ├── scripts/ │ ├── cspell.json │ ├── increment_version.cjs │ ├── tsconfig.build.json │ ├── typedoc.json │ └── webpack.config.cjs ├── test/ │ ├── README.md │ ├── helper/ │ │ ├── Basic.ts │ │ ├── CompareToFile.ts │ │ ├── Connect.ts │ │ ├── ConstantOutput.ts │ │ ├── Dispose.ts │ │ ├── EffectTests.ts │ │ ├── InstrumentTests.ts │ │ ├── MonophonicTests.ts │ │ ├── Offline.ts │ │ ├── OscillatorTests.ts │ │ ├── OutputAudio.ts │ │ ├── PassAudio.ts │ │ ├── SignalTests.ts │ │ ├── SourceTests.ts │ │ ├── StereoSignal.ts │ │ └── compare/ │ │ ├── Compare.ts │ │ ├── OfflineRender.ts │ │ ├── Plot.ts │ │ ├── Spectrum.ts │ │ ├── TestAudioBuffer.ts │ │ └── index.ts │ ├── integration/ │ │ ├── node/ │ │ │ ├── package.json │ │ │ └── test.mjs │ │ ├── typescript/ │ │ │ ├── package.json │ │ │ └── test.ts │ │ ├── unpkg/ │ │ │ ├── package.json │ │ │ └── test.mjs │ │ ├── vite/ │ │ │ ├── index.html │ │ │ ├── index.ts │ │ │ └── package.json │ │ └── webpack/ │ │ ├── package.json │ │ └── test.js │ ├── scripts/ │ │ ├── test_examples.mjs │ │ ├── test_html.mjs │ │ ├── test_integrations.mjs │ │ ├── test_readme.mjs │ │ └── utils.mjs │ └── web-test-runner.config.js └── tsconfig.json
SYMBOL INDEX (2170 symbols across 221 files)
FILE: Tone/component/analysis/Analyser.ts
type AnalyserType (line 13) | type AnalyserType = "fft" | "waveform";
type AnalyserOptions (line 15) | interface AnalyserOptions extends ToneAudioNodeOptions {
class Analyser (line 27) | class Analyser extends ToneAudioNode<AnalyserOptions> {
method constructor (line 64) | constructor() {
method getDefaults (line 96) | static getDefaults(): AnalyserOptions {
method getValue (line 111) | getValue(): Float32Array | Float32Array[] {
method size (line 130) | get size(): PowerOfTwo {
method size (line 133) | set size(size: PowerOfTwo) {
method channels (line 144) | get channels(): number {
method type (line 151) | get type(): AnalyserType {
method type (line 154) | set type(type: AnalyserType) {
method smoothing (line 165) | get smoothing(): NormalRange {
method smoothing (line 168) | set smoothing(val: NormalRange) {
method dispose (line 175) | dispose(): this {
FILE: Tone/component/analysis/DCMeter.ts
type DCMeterOptions (line 4) | type DCMeterOptions = MeterBaseOptions;
class DCMeter (line 20) | class DCMeter extends MeterBase<DCMeterOptions> {
method constructor (line 24) | constructor() {
method getValue (line 34) | getValue(): number {
FILE: Tone/component/analysis/FFT.ts
type FFTOptions (line 8) | interface FFTOptions extends MeterBaseOptions {
class FFT (line 19) | class FFT extends MeterBase<FFTOptions> {
method constructor (line 34) | constructor() {
method getDefaults (line 45) | static getDefaults(): FFTOptions {
method getValue (line 57) | getValue(): Float32Array {
method size (line 67) | get size(): PowerOfTwo {
method size (line 70) | set size(size) {
method smoothing (line 77) | get smoothing(): NormalRange {
method smoothing (line 80) | set smoothing(val) {
method getFrequencyOfIndex (line 90) | getFrequencyOfIndex(index: number): Hertz {
FILE: Tone/component/analysis/Follower.ts
type FollowerOptions (line 12) | interface FollowerOptions extends ToneAudioNodeOptions {
class Follower (line 26) | class Follower extends ToneAudioNode<FollowerOptions> {
method constructor (line 52) | constructor() {
method getDefaults (line 70) | static getDefaults(): FollowerOptions {
method smoothing (line 79) | get smoothing(): Time {
method smoothing (line 82) | set smoothing(smoothing) {
method dispose (line 87) | dispose(): this {
FILE: Tone/component/analysis/Meter.ts
type MeterOptions (line 8) | interface MeterOptions extends MeterBaseOptions {
class Meter (line 32) | class Meter extends MeterBase<MeterOptions> {
method constructor (line 57) | constructor() {
method getDefaults (line 79) | static getDefaults(): MeterOptions {
method getLevel (line 91) | getLevel(): number | number[] {
method getValue (line 108) | getValue(): number | number[] {
method channels (line 144) | get channels(): number {
method dispose (line 148) | dispose(): this {
FILE: Tone/component/analysis/MeterBase.ts
type MeterBaseOptions (line 10) | type MeterBaseOptions = ToneAudioNodeOptions;
class MeterBase (line 15) | class MeterBase<
method constructor (line 36) | constructor() {
method dispose (line 49) | dispose(): this {
FILE: Tone/component/analysis/Waveform.ts
type WaveformOptions (line 5) | interface WaveformOptions extends MeterBaseOptions {
class Waveform (line 16) | class Waveform extends MeterBase<WaveformOptions> {
method constructor (line 24) | constructor() {
method getDefaults (line 36) | static getDefaults(): WaveformOptions {
method getValue (line 46) | getValue(): Float32Array {
method size (line 54) | get size(): PowerOfTwo {
method size (line 57) | set size(size) {
FILE: Tone/component/channel/Channel.ts
type ChannelOptions (line 15) | interface ChannelOptions extends ToneAudioNodeOptions {
class Channel (line 31) | class Channel extends ToneAudioNode<ChannelOptions> {
method constructor (line 65) | constructor() {
method getDefaults (line 90) | static getDefaults(): ChannelOptions {
method solo (line 103) | get solo(): boolean {
method solo (line 106) | set solo(solo) {
method muted (line 114) | get muted(): boolean {
method mute (line 121) | get mute(): boolean {
method mute (line 124) | set mute(mute) {
method _getBus (line 138) | private _getBus(name: string): Gain {
method send (line 155) | send(name: string, volume: Decibels = 0): Gain<"decibels"> {
method receive (line 171) | receive(name: string): this {
method dispose (line 177) | dispose(): this {
FILE: Tone/component/channel/CrossFade.ts
type CrossFadeOptions (line 14) | interface CrossFadeOptions extends ToneAudioNodeOptions {
class CrossFade (line 44) | class CrossFade extends ToneAudioNode<CrossFadeOptions> {
method constructor (line 108) | constructor() {
method getDefaults (line 143) | static getDefaults(): CrossFadeOptions {
method dispose (line 149) | dispose(): this {
FILE: Tone/component/channel/Merge.ts
type MergeOptions (line 8) | interface MergeOptions extends ToneAudioNodeOptions {
class Merge (line 23) | class Merge extends ToneAudioNode<MergeOptions> {
method constructor (line 46) | constructor() {
method getDefaults (line 58) | static getDefaults(): MergeOptions {
method dispose (line 64) | dispose(): this {
FILE: Tone/component/channel/MidSideMerge.ts
type MidSideMergeOptions (line 12) | type MidSideMergeOptions = ToneAudioNodeOptions;
class MidSideMerge (line 22) | class MidSideMerge extends ToneAudioNode<MidSideMergeOptions> {
method constructor (line 71) | constructor() {
method dispose (line 97) | dispose(): this {
FILE: Tone/component/channel/MidSideSplit.ts
type MidSideSplitOptions (line 11) | type MidSideSplitOptions = ToneAudioNodeOptions;
class MidSideSplit (line 22) | class MidSideSplit extends ToneAudioNode<MidSideSplitOptions> {
method constructor (line 57) | constructor() {
method dispose (line 83) | dispose(): this {
FILE: Tone/component/channel/Mono.ts
type MonoOptions (line 10) | type MonoOptions = ToneAudioNodeOptions;
class Mono (line 18) | class Mono extends ToneAudioNode<MonoOptions> {
method constructor (line 37) | constructor() {
method dispose (line 51) | dispose(): this {
FILE: Tone/component/channel/MultibandSplit.ts
type MultibandSplitOptions (line 12) | interface MultibandSplitOptions extends ToneAudioNodeOptions {
class MultibandSplit (line 36) | class MultibandSplit extends ToneAudioNode<MultibandSplitOptions> {
method constructor (line 108) | constructor() {
method getDefaults (line 148) | static getDefaults(): MultibandSplitOptions {
method dispose (line 159) | dispose(): this {
FILE: Tone/component/channel/PanVol.ts
type PanVolOptions (line 14) | interface PanVolOptions extends ToneAudioNodeOptions {
class PanVol (line 29) | class PanVol extends ToneAudioNode<PanVolOptions> {
method constructor (line 63) | constructor() {
method getDefaults (line 89) | static getDefaults(): PanVolOptions {
method mute (line 101) | get mute(): boolean {
method mute (line 104) | set mute(mute) {
method dispose (line 108) | dispose(): this {
FILE: Tone/component/channel/Panner.ts
type TonePannerOptions (line 10) | interface TonePannerOptions extends ToneAudioNodeOptions {
class Panner (line 26) | class Panner extends ToneAudioNode<TonePannerOptions> {
method constructor (line 56) | constructor() {
method getDefaults (line 80) | static getDefaults(): TonePannerOptions {
method dispose (line 87) | dispose(): this {
FILE: Tone/component/channel/Panner3D.ts
type Panner3DOptions (line 11) | interface Panner3DOptions extends ToneAudioNodeOptions {
class Panner3D (line 32) | class Panner3D extends ToneAudioNode<Panner3DOptions> {
method constructor (line 57) | constructor() {
method getDefaults (line 108) | static getDefaults(): Panner3DOptions {
method setPosition (line 130) | setPosition(x: number, y: number, z: number): this {
method setOrientation (line 140) | setOrientation(x: number, y: number, z: number): this {
method panningModel (line 150) | get panningModel(): PanningModelType {
method panningModel (line 153) | set panningModel(val) {
method refDistance (line 160) | get refDistance(): number {
method refDistance (line 163) | set refDistance(val) {
method rolloffFactor (line 170) | get rolloffFactor(): number {
method rolloffFactor (line 173) | set rolloffFactor(val) {
method distanceModel (line 180) | get distanceModel(): DistanceModelType {
method distanceModel (line 183) | set distanceModel(val) {
method coneInnerAngle (line 190) | get coneInnerAngle(): Degrees {
method coneInnerAngle (line 193) | set coneInnerAngle(val) {
method coneOuterAngle (line 201) | get coneOuterAngle(): Degrees {
method coneOuterAngle (line 204) | set coneOuterAngle(val) {
method coneOuterGain (line 211) | get coneOuterGain(): GainFactor {
method coneOuterGain (line 214) | set coneOuterGain(val) {
method maxDistance (line 222) | get maxDistance(): number {
method maxDistance (line 225) | set maxDistance(val) {
method dispose (line 229) | dispose(): this {
FILE: Tone/component/channel/Recorder.test.ts
function wait (line 50) | function wait(time) {
FILE: Tone/component/channel/Recorder.ts
type RecorderOptions (line 11) | interface RecorderOptions extends ToneAudioNodeOptions {
class Recorder (line 42) | class Recorder extends ToneAudioNode<RecorderOptions> {
method constructor (line 59) | constructor() {
method getDefaults (line 76) | static getDefaults(): RecorderOptions {
method mimeType (line 84) | get mimeType(): string {
method supported (line 92) | static get supported(): boolean {
method state (line 99) | get state(): PlaybackState {
method start (line 113) | async start() {
method stop (line 136) | async stop(): Promise<Blob> {
method pause (line 158) | pause(): this {
method dispose (line 164) | dispose(): this {
FILE: Tone/component/channel/Solo.ts
type SoloOptions (line 9) | interface SoloOptions extends ToneAudioNodeOptions {
class Solo (line 25) | class Solo extends ToneAudioNode<SoloOptions> {
method constructor (line 36) | constructor() {
method getDefaults (line 55) | static getDefaults(): SoloOptions {
method solo (line 76) | get solo(): boolean {
method solo (line 79) | set solo(solo) {
method muted (line 93) | get muted(): boolean {
method _addSolo (line 100) | private _addSolo(): void {
method _removeSolo (line 110) | private _removeSolo(): void {
method _isSoloed (line 119) | private _isSoloed(): boolean {
method _noSolos (line 129) | private _noSolos(): boolean {
method _updateSolo (line 142) | private _updateSolo(): void {
method dispose (line 153) | dispose(): this {
FILE: Tone/component/channel/Split.ts
type SplitOptions (line 7) | interface SplitOptions extends ToneAudioNodeOptions {
class Split (line 19) | class Split extends ToneAudioNode<SplitOptions> {
method constructor (line 35) | constructor() {
method getDefaults (line 48) | static getDefaults(): SplitOptions {
method dispose (line 54) | dispose(): this {
FILE: Tone/component/channel/Volume.ts
type VolumeOptions (line 11) | interface VolumeOptions extends ToneAudioNodeOptions {
class Volume (line 24) | class Volume extends ToneAudioNode<VolumeOptions> {
method constructor (line 56) | constructor() {
method getDefaults (line 75) | static getDefaults(): VolumeOptions {
method mute (line 90) | get mute(): boolean {
method mute (line 93) | set mute(mute: boolean) {
method dispose (line 106) | dispose(): this {
FILE: Tone/component/dynamics/Compressor.ts
type CompressorOptions (line 10) | interface CompressorOptions extends ToneAudioNodeOptions {
class Compressor (line 28) | class Compressor extends ToneAudioNode<CompressorOptions> {
method constructor (line 81) | constructor() {
method getDefaults (line 141) | static getDefaults(): CompressorOptions {
method reduction (line 155) | get reduction(): Decibels {
method dispose (line 159) | dispose(): this {
FILE: Tone/component/dynamics/Gate.ts
type GateOptions (line 12) | interface GateOptions extends ToneAudioNodeOptions {
class Gate (line 29) | class Gate extends ToneAudioNode<GateOptions> {
method constructor (line 56) | constructor() {
method getDefaults (line 80) | static getDefaults(): GateOptions {
method threshold (line 90) | get threshold(): Decibels {
method threshold (line 93) | set threshold(thresh) {
method smoothing (line 101) | get smoothing(): Time {
method smoothing (line 104) | set smoothing(smoothingTime) {
method dispose (line 108) | dispose(): this {
FILE: Tone/component/dynamics/Limiter.ts
type LimiterOptions (line 13) | interface LimiterOptions extends ToneAudioNodeOptions {
class Limiter (line 28) | class Limiter extends ToneAudioNode<LimiterOptions> {
method constructor (line 46) | constructor() {
method getDefaults (line 67) | static getDefaults(): LimiterOptions {
method reduction (line 77) | get reduction(): Decibels {
method dispose (line 81) | dispose(): this {
FILE: Tone/component/dynamics/MidSideCompressor.ts
type MidSideCompressorOptions (line 13) | interface MidSideCompressorOptions extends ToneAudioNodeOptions {
class MidSideCompressor (line 24) | class MidSideCompressor extends ToneAudioNode<MidSideCompressorOptions> {
method constructor (line 51) | constructor() {
method getDefaults (line 76) | static getDefaults(): MidSideCompressorOptions {
method dispose (line 95) | dispose(): this {
FILE: Tone/component/dynamics/MultibandCompressor.ts
type MultibandCompressorOptions (line 14) | interface MultibandCompressorOptions extends ToneAudioNodeOptions {
class MultibandCompressor (line 36) | class MultibandCompressor extends ToneAudioNode<MultibandCompressorOptio...
method constructor (line 73) | constructor() {
method getDefaults (line 106) | static getDefaults(): MultibandCompressorOptions {
method dispose (line 134) | dispose(): this {
FILE: Tone/component/envelope/AmplitudeEnvelope.ts
class AmplitudeEnvelope (line 28) | class AmplitudeEnvelope extends Envelope {
method constructor (line 54) | constructor() {
method dispose (line 71) | dispose(): this {
FILE: Tone/component/envelope/Envelope.ts
type BasicEnvelopeCurve (line 18) | type BasicEnvelopeCurve = "linear" | "exponential";
type InternalEnvelopeCurve (line 19) | type InternalEnvelopeCurve = BasicEnvelopeCurve | number[];
type EnvelopeCurve (line 20) | type EnvelopeCurve = EnvelopeCurveName | number[];
type EnvelopeOptions (line 22) | interface EnvelopeOptions extends ToneAudioNodeOptions {
class Envelope (line 59) | class Envelope extends ToneAudioNode<EnvelopeOptions> {
method constructor (line 192) | constructor() {
method getDefaults (line 209) | static getDefaults(): EnvelopeOptions {
method value (line 225) | get value(): NormalRange {
method _getCurve (line 235) | private _getCurve(
method _setCurve (line 260) | private _setCurve(
method attackCurve (line 303) | get attackCurve(): EnvelopeCurve {
method attackCurve (line 306) | set attackCurve(curve) {
method releaseCurve (line 323) | get releaseCurve(): EnvelopeCurve {
method releaseCurve (line 326) | set releaseCurve(curve) {
method decayCurve (line 342) | get decayCurve(): EnvelopeCurve {
method decayCurve (line 345) | set decayCurve(curve) {
method triggerAttack (line 360) | triggerAttack(time?: Time, velocity: NormalRange = 1): this {
method triggerRelease (line 432) | triggerRelease(time?: Time): this {
method getValueAtTime (line 469) | getValueAtTime(time: Time): NormalRange {
method triggerAttackRelease (line 485) | triggerAttackRelease(
method cancel (line 499) | cancel(after?: Time): this {
method connect (line 507) | connect(destination: InputNode, outputNumber = 0, inputNumber = 0): th...
method disconnect (line 513) | disconnect(
method asArray (line 527) | async asArray(length = 1024): Promise<Float32Array> {
method dispose (line 560) | dispose(): this {
type EnvelopeCurveObject (line 567) | interface EnvelopeCurveObject {
type EnvelopeDirection (line 572) | type EnvelopeDirection = keyof EnvelopeCurveObject;
type EnvelopeCurveMap (line 574) | interface EnvelopeCurveMap {
type EnvelopeCurveName (line 584) | type EnvelopeCurveName = keyof EnvelopeCurveMap;
function invertCurve (line 638) | function invertCurve(curve: number[]): number[] {
function reverseCurve (line 649) | function reverseCurve(curve: number[]): number[] {
FILE: Tone/component/envelope/FrequencyEnvelope.ts
type FrequencyEnvelopeOptions (line 8) | interface FrequencyEnvelopeOptions extends EnvelopeOptions {
class FrequencyEnvelope (line 28) | class FrequencyEnvelope extends Envelope {
method constructor (line 64) | constructor() {
method getDefaults (line 87) | static getDefaults(): FrequencyEnvelopeOptions {
method baseFrequency (line 99) | get baseFrequency(): Frequency {
method baseFrequency (line 102) | set baseFrequency(min) {
method octaves (line 115) | get octaves(): number {
method octaves (line 118) | set octaves(octaves: number) {
method exponent (line 126) | get exponent(): number {
method exponent (line 129) | set exponent(exponent) {
method dispose (line 136) | dispose(): this {
FILE: Tone/component/filter/BiquadFilter.ts
type BiquadFilterOptions (line 10) | interface BiquadFilterOptions extends ToneAudioNodeOptions {
class BiquadFilter (line 23) | class BiquadFilter extends ToneAudioNode<BiquadFilterOptions> {
method constructor (line 63) | constructor() {
method getDefaults (line 106) | static getDefaults(): BiquadFilterOptions {
method type (line 120) | get type(): BiquadFilterType {
method type (line 123) | set type(type) {
method getFrequencyResponse (line 144) | getFrequencyResponse(len = 128): Float32Array {
method dispose (line 164) | dispose(): this {
FILE: Tone/component/filter/Convolver.test.ts
method onload (line 38) | onload(): void {
method onload (line 74) | onload(): void {
method onload (line 89) | onload(): void {
FILE: Tone/component/filter/Convolver.ts
type ConvolverOptions (line 10) | interface ConvolverOptions extends ToneAudioNodeOptions {
class Convolver (line 27) | class Convolver extends ToneAudioNode<ConvolverOptions> {
method constructor (line 52) | constructor() {
method getDefaults (line 80) | static getDefaults(): ConvolverOptions {
method load (line 93) | async load(url: string): Promise<void> {
method buffer (line 100) | get buffer(): ToneAudioBuffer | null {
method buffer (line 107) | set buffer(buffer) {
method normalize (line 129) | get normalize(): boolean {
method normalize (line 132) | set normalize(norm) {
method dispose (line 136) | dispose(): this {
FILE: Tone/component/filter/EQ3.ts
type EQ3Options (line 13) | interface EQ3Options extends ToneAudioNodeOptions {
class EQ3 (line 25) | class EQ3 extends ToneAudioNode<EQ3Options> {
method constructor (line 92) | constructor() {
method getDefaults (line 140) | static getDefaults(): EQ3Options {
method dispose (line 153) | dispose(): this {
FILE: Tone/component/filter/FeedbackCombFilter.ts
type FeedbackCombFilterOptions (line 14) | interface FeedbackCombFilterOptions extends ToneAudioNodeOptions {
class FeedbackCombFilter (line 28) | class FeedbackCombFilter extends ToneAudioWorklet<FeedbackCombFilterOpti...
method constructor (line 50) | constructor() {
method _audioWorkletName (line 82) | protected _audioWorkletName(): string {
method getDefaults (line 89) | static getDefaults(): FeedbackCombFilterOptions {
method onReady (line 96) | onReady(node: AudioWorkletNode) {
method dispose (line 104) | dispose(): this {
FILE: Tone/component/filter/Filter.ts
type FilterRollOff (line 14) | type FilterRollOff = -12 | -24 | -48 | -96;
type FilterOptions (line 16) | type FilterOptions = BiquadFilterOptions & {
class Filter (line 31) | class Filter extends ToneAudioNode<FilterOptions> {
method constructor (line 75) | constructor() {
method getDefaults (line 111) | static getDefaults(): FilterOptions {
method type (line 126) | get type(): BiquadFilterType {
method type (line 129) | set type(type: BiquadFilterType) {
method rolloff (line 150) | get rolloff(): FilterRollOff {
method rolloff (line 153) | set rolloff(rolloff) {
method getFrequencyResponse (line 192) | getFrequencyResponse(len = 128): Float32Array {
method dispose (line 214) | dispose(): this {
FILE: Tone/component/filter/LowpassCombFilter.ts
type LowpassCombFilterOptions (line 14) | interface LowpassCombFilterOptions extends ToneAudioNodeOptions {
class LowpassCombFilter (line 25) | class LowpassCombFilter extends ToneAudioNode<LowpassCombFilterOptions> {
method constructor (line 62) | constructor() {
method getDefaults (line 88) | static getDefaults(): LowpassCombFilterOptions {
method dampening (line 99) | get dampening(): Frequency {
method dampening (line 102) | set dampening(fq) {
method dispose (line 106) | dispose(): this {
FILE: Tone/component/filter/OnePoleFilter.ts
type OnePoleFilterType (line 9) | type OnePoleFilterType = "highpass" | "lowpass";
type OnePoleFilterOptions (line 11) | interface OnePoleFilterOptions extends ToneAudioNodeOptions {
class OnePoleFilter (line 26) | class OnePoleFilter extends ToneAudioNode<OnePoleFilterOptions> {
method constructor (line 53) | constructor() {
method getDefaults (line 68) | static getDefaults(): OnePoleFilterOptions {
method _createFilter (line 78) | private _createFilter() {
method frequency (line 106) | get frequency(): Frequency {
method frequency (line 109) | set frequency(fq) {
method type (line 117) | get type(): OnePoleFilterType {
method type (line 120) | set type(t) {
method getFrequencyResponse (line 131) | getFrequencyResponse(len = 128): Float32Array {
method dispose (line 144) | dispose(): this {
FILE: Tone/component/filter/PhaseShiftAllpass.ts
class PhaseShiftAllpass (line 16) | class PhaseShiftAllpass extends ToneAudioNode<ToneAudioNodeOptions> {
method constructor (line 46) | constructor(options?: Partial<ToneAudioNodeOptions>) {
method _createAllPassFilterBank (line 76) | private _createAllPassFilterBank(bankValues: number[]): IIRFilterNode[] {
method dispose (line 91) | dispose(): this {
FILE: Tone/core/Global.ts
function getContext (line 31) | function getContext(): BaseContext {
function setContext (line 44) | function setContext(
function start (line 74) | function start(): Promise<void> {
FILE: Tone/core/Tone.ts
type BaseToneOptions (line 15) | interface BaseToneOptions {}
method getDefaults (line 37) | static getDefaults(): BaseToneOptions {
method log (line 62) | protected log(...args: any[]): void {
method dispose (line 85) | dispose(): this {
method disposed (line 95) | get disposed(): boolean {
method toString (line 105) | toString(): string {
FILE: Tone/core/clock/Clock.test.ts
method callback (line 29) | callback(): void {
FILE: Tone/core/clock/Clock.ts
type ClockCallback (line 14) | type ClockCallback = (time: Seconds, ticks?: Ticks) => void;
type ClockOptions (line 16) | interface ClockOptions extends ToneWithContextOptions {
type ClockEvent (line 22) | type ClockEvent = "start" | "stop" | "pause";
class Clock (line 42) | class Clock<TypeName extends "bpm" | "hertz" = "hertz">
method constructor (line 85) | constructor() {
method getDefaults (line 109) | static getDefaults(): ClockOptions {
method state (line 120) | get state(): PlaybackState {
method start (line 129) | start(time?: Time, offset?: Ticks): this {
method stop (line 156) | stop(time?: Time): this {
method pause (line 172) | pause(time?: Time): this {
method ticks (line 189) | get ticks(): Ticks {
method ticks (line 192) | set ticks(t: Ticks) {
method seconds (line 201) | get seconds(): Seconds {
method seconds (line 204) | set seconds(s: Seconds) {
method getSecondsAtTime (line 213) | getSecondsAtTime(time: Time): Seconds {
method setTicksAtTime (line 222) | setTicksAtTime(ticks: Ticks, time: Time): this {
method getTimeOfTick (line 238) | getTimeOfTick(tick: Ticks, before = this.now()): Seconds {
method getTicksAtTime (line 247) | getTicksAtTime(time?: Time): Ticks {
method nextTickTime (line 255) | nextTickTime(offset: Ticks, when: Time): Seconds {
method _loop (line 267) | private _loop(): void {
method getStateAtTime (line 311) | getStateAtTime(time: Time): PlaybackState {
method dispose (line 319) | dispose(): this {
FILE: Tone/core/clock/TickParam.ts
type TickAutomationEvent (line 7) | type TickAutomationEvent = AutomationEvent & {
type TickParamOptions (line 11) | interface TickParamOptions<TypeName extends UnitName>
class TickParam (line 21) | class TickParam<
method constructor (line 46) | constructor() {
method getDefaults (line 69) | static getDefaults(): TickParamOptions<any> {
method setTargetAtTime (line 77) | setTargetAtTime(
method setValueAtTime (line 104) | setValueAtTime(value: UnitMap[TypeName], time: Time): this {
method linearRampToValueAtTime (line 117) | linearRampToValueAtTime(value: UnitMap[TypeName], time: Time): this {
method exponentialRampToValueAtTime (line 130) | exponentialRampToValueAtTime(value: UnitMap[TypeName], time: Time): th...
method _getTicksUntilEvent (line 160) | private _getTicksUntilEvent(
method getTicksAtTime (line 195) | getTicksAtTime(time: Time): Ticks {
method getDurationOfTicks (line 207) | getDurationOfTicks(ticks: Ticks, time: Time): Seconds {
method getTimeOfTick (line 217) | getTimeOfTick(tick: Ticks): Seconds {
method ticksToTime (line 255) | ticksToTime(ticks: Ticks, when: Time): Seconds {
method timeToTicks (line 267) | timeToTicks(duration: Time, when: Time): Ticks {
method _fromType (line 278) | protected _fromType(val: UnitMap[TypeName]): number {
method _toType (line 289) | protected _toType(val: number): UnitMap[TypeName] {
method multiplier (line 299) | get multiplier(): number {
method multiplier (line 302) | set multiplier(m: number) {
FILE: Tone/core/clock/TickSignal.ts
type TickSignalOptions (line 7) | interface TickSignalOptions<TypeName extends UnitName>
class TickSignal (line 22) | class TickSignal<
method constructor (line 38) | constructor() {
method getDefaults (line 56) | static getDefaults(): TickSignalOptions<any> {
method ticksToTime (line 64) | ticksToTime(ticks: Ticks, when: Time): Seconds {
method timeToTicks (line 68) | timeToTicks(duration: Time, when: Time): Ticks {
method getTimeOfTick (line 72) | getTimeOfTick(tick: Ticks): Seconds {
method getDurationOfTicks (line 76) | getDurationOfTicks(ticks: Ticks, time: Time): Seconds {
method getTicksAtTime (line 80) | getTicksAtTime(time: Time): Ticks {
method multiplier (line 87) | get multiplier(): number {
method multiplier (line 90) | set multiplier(m: number) {
method dispose (line 94) | dispose(): this {
FILE: Tone/core/clock/TickSource.ts
type TickSourceOptions (line 18) | interface TickSourceOptions extends ToneWithContextOptions {
type TickSourceOffsetEvent (line 23) | interface TickSourceOffsetEvent extends TimelineEvent {
type TickSourceTicksAtTimeEvent (line 29) | interface TickSourceTicksAtTimeEvent extends TimelineEvent {
type TickSourceSecondsAtTimeEvent (line 35) | interface TickSourceSecondsAtTimeEvent extends TimelineEvent {
class TickSource (line 44) | class TickSource<
method constructor (line 81) | constructor() {
method getDefaults (line 102) | static getDefaults(): TickSourceOptions {
method state (line 115) | get state(): PlaybackState {
method start (line 125) | start(time: Time, offset?: Ticks): this {
method stop (line 142) | stop(time: Time): this {
method pause (line 164) | pause(time: Time): this {
method cancel (line 178) | cancel(time: Time): this {
method getTicksAtTime (line 192) | getTicksAtTime(time?: Time): Ticks {
method ticks (line 259) | get ticks(): Ticks {
method ticks (line 262) | set ticks(t: Ticks) {
method seconds (line 270) | get seconds(): Seconds {
method seconds (line 273) | set seconds(s: Seconds) {
method getSecondsAtTime (line 284) | getSecondsAtTime(time: Time): Seconds {
method setTicksAtTime (line 346) | setTicksAtTime(ticks: Ticks, time: Time): this {
method getStateAtTime (line 363) | getStateAtTime(time: Time): PlaybackState {
method getTimeOfTick (line 376) | getTimeOfTick(tick: Ticks, before = this.now()): Seconds {
method forEachTickBetween (line 392) | forEachTickBetween(
method dispose (line 457) | dispose(): this {
FILE: Tone/core/clock/Ticker.test.ts
function empty (line 6) | function empty(): void {
FILE: Tone/core/clock/Ticker.ts
type TickerClockSource (line 3) | type TickerClockSource = "worker" | "timeout" | "offline";
class Ticker (line 9) | class Ticker {
method constructor (line 40) | constructor(
method _createWorker (line 61) | private _createWorker(): void {
method _createTimeout (line 94) | private _createTimeout(): void {
method _createClock (line 104) | private _createClock(): void {
method _disposeClock (line 122) | private _disposeClock(): void {
method updateInterval (line 135) | get updateInterval(): Seconds {
method updateInterval (line 138) | set updateInterval(interval: Seconds) {
method type (line 148) | get type(): TickerClockSource {
method type (line 151) | set type(type: TickerClockSource) {
method dispose (line 160) | dispose(): void {
FILE: Tone/core/clock/Transport.ts
type TransportOptions (line 42) | interface TransportOptions extends ToneWithContextOptions {
type TransportEventNames (line 52) | type TransportEventNames =
type SyncedSignalEvent (line 61) | interface SyncedSignalEvent {
type TransportCallback (line 67) | type TransportCallback = (time: Seconds) => void;
class TransportInstance (line 93) | class TransportInstance
method constructor (line 193) | constructor() {
method getDefaults (line 219) | static getDefaults(): TransportOptions {
method _processTick (line 239) | private _processTick(tickTime: Seconds, ticks: Ticks): void {
method schedule (line 292) | schedule(
method scheduleRepeat (line 320) | scheduleRepeat(
method scheduleOnce (line 343) | scheduleOnce(
method clear (line 359) | clear(eventId: number): this {
method _addEvent (line 374) | private _addEvent(
method cancel (line 392) | cancel(after: TransportTime = 0): this {
method _bindClockEvents (line 410) | private _bindClockEvents(): void {
method state (line 428) | get state(): PlaybackState {
method start (line 440) | start(time?: Time, offset?: TransportTime): this {
method stop (line 458) | stop(time?: Time): this {
method pause (line 466) | pause(time?: Time): this {
method toggle (line 478) | toggle(time?: Time): this {
method timeSignature (line 503) | get timeSignature(): TimeSignature {
method timeSignature (line 506) | set timeSignature(timeSig: TimeSignature) {
method loopStart (line 516) | get loopStart(): Time {
method loopStart (line 519) | set loopStart(startPosition: Time) {
method loopEnd (line 526) | get loopEnd(): Time {
method loopEnd (line 529) | set loopEnd(endPosition: Time) {
method loop (line 536) | get loop(): boolean {
method loop (line 539) | set loop(loop) {
method setLoopPoints (line 550) | setLoopPoints(
method swing (line 562) | get swing(): NormalRange {
method swing (line 565) | set swing(amount: NormalRange) {
method swingSubdivision (line 575) | get swingSubdivision(): Subdivision {
method swingSubdivision (line 578) | set swingSubdivision(subdivision: Subdivision) {
method position (line 586) | get position(): BarsBeatsSixteenths | Time {
method position (line 591) | set position(progress: Time) {
method seconds (line 600) | get seconds(): Seconds {
method seconds (line 603) | set seconds(s: Seconds) {
method progress (line 613) | get progress(): NormalRange {
method ticks (line 628) | get ticks(): Ticks {
method ticks (line 631) | set ticks(t: Ticks) {
method getTicksAtTime (line 665) | getTicksAtTime(time?: Time): Ticks {
method setTicksAtTime (line 674) | setTicksAtTime(ticks: Ticks, time: Time): this {
method getSecondsAtTime (line 684) | getSecondsAtTime(time: Time): Seconds {
method setSecondsAtTime (line 693) | setSecondsAtTime(seconds: Seconds, time: Time): this {
method PPQ (line 704) | get PPQ(): number {
method PPQ (line 707) | set PPQ(ppq: number) {
method nextSubdivision (line 727) | nextSubdivision(subdivision?: Time): Seconds {
method syncSignal (line 750) | syncSignal(signal: Signal<any>, ratio?: number): this {
method unsyncSignal (line 800) | unsyncSignal(signal: Signal<any>): this {
method dispose (line 815) | dispose(): this {
FILE: Tone/core/clock/TransportEvent.ts
type TransportEventOptions (line 5) | interface TransportEventOptions {
class TransportEvent (line 16) | class TransportEvent {
method constructor (line 51) | constructor(transport: Transport, opts: Partial<TransportEventOptions>) {
method getDefaults (line 64) | static getDefaults(): TransportEventOptions {
method floatTime (line 80) | protected get floatTime(): number {
method invoke (line 88) | invoke(time: Seconds): void {
method dispose (line 101) | dispose(): this {
FILE: Tone/core/clock/TransportRepeatEvent.ts
type TransportRepeatEventOptions (line 8) | interface TransportRepeatEventOptions extends TransportEventOptions {
class TransportRepeatEvent (line 17) | class TransportRepeatEvent extends TransportEvent {
method constructor (line 56) | constructor(
method getDefaults (line 74) | static getDefaults(): TransportRepeatEventOptions {
method invoke (line 87) | invoke(time: Seconds): void {
method _createEvent (line 97) | private _createEvent(): number {
method _createEvents (line 110) | private _createEvents(): void {
method _restart (line 127) | private _restart(time?: Time): void {
method dispose (line 148) | dispose(): this {
FILE: Tone/core/context/AudioContext.ts
function createAudioContext (line 13) | function createAudioContext(
function createOfflineAudioContext (line 22) | function createOfflineAudioContext(
type AnyAudioContext (line 37) | type AnyAudioContext = AudioContext | OfflineAudioContext;
type ToneWindow (line 42) | interface ToneWindow extends Window {
function createAudioWorkletNode (line 65) | function createAudioWorkletNode(
FILE: Tone/core/context/BaseContext.ts
type ExcludedFromBaseAudioContext (line 10) | type ExcludedFromBaseAudioContext =
type BaseAudioContextSubset (line 21) | type BaseAudioContextSubset = Omit<
type ContextLatencyHint (line 26) | type ContextLatencyHint = AudioContextLatencyCategory;
method toJSON (line 160) | toJSON(): Record<string, any> {
FILE: Tone/core/context/Context.test.ts
function checkDone (line 226) | function checkDone(id: number) {
FILE: Tone/core/context/Context.ts
type ContextOptions (line 20) | interface ContextOptions {
type ContextTimeoutEvent (line 29) | interface ContextTimeoutEvent {
class Context (line 39) | class Context extends BaseContext {
method constructor (line 109) | constructor() {
method getDefaults (line 154) | static getDefaults(): ContextOptions {
method initialize (line 166) | private initialize(): this {
method createAnalyser (line 179) | createAnalyser(): AnalyserNode {
method createOscillator (line 182) | createOscillator(): OscillatorNode {
method createBufferSource (line 185) | createBufferSource(): AudioBufferSourceNode {
method createBiquadFilter (line 188) | createBiquadFilter(): BiquadFilterNode {
method createBuffer (line 191) | createBuffer(
method createChannelMerger (line 198) | createChannelMerger(
method createChannelSplitter (line 203) | createChannelSplitter(
method createConstantSource (line 208) | createConstantSource(): ConstantSourceNode {
method createConvolver (line 211) | createConvolver(): ConvolverNode {
method createDelay (line 214) | createDelay(maxDelayTime?: number | undefined): DelayNode {
method createDynamicsCompressor (line 217) | createDynamicsCompressor(): DynamicsCompressorNode {
method createGain (line 220) | createGain(): GainNode {
method createIIRFilter (line 223) | createIIRFilter(
method createPanner (line 230) | createPanner(): PannerNode {
method createPeriodicWave (line 233) | createPeriodicWave(
method createStereoPanner (line 240) | createStereoPanner(): StereoPannerNode {
method createWaveShaper (line 243) | createWaveShaper(): WaveShaperNode {
method createMediaStreamSource (line 246) | createMediaStreamSource(stream: MediaStream): MediaStreamAudioSourceNo...
method createMediaElementSource (line 254) | createMediaElementSource(
method createMediaStreamDestination (line 264) | createMediaStreamDestination(): MediaStreamAudioDestinationNode {
method decodeAudioData (line 272) | decodeAudioData(audioData: ArrayBuffer): Promise<AudioBuffer> {
method currentTime (line 279) | get currentTime(): Seconds {
method state (line 285) | get state(): AudioContextState {
method sampleRate (line 291) | get sampleRate(): number {
method listener (line 298) | get listener(): Listener {
method listener (line 302) | set listener(l) {
method transport (line 313) | get transport(): Transport {
method transport (line 317) | set transport(t: Transport) {
method draw (line 328) | get draw(): Draw {
method draw (line 332) | set draw(d) {
method destination (line 340) | get destination(): Destination {
method destination (line 344) | set destination(d: Destination) {
method createAudioWorkletNode (line 365) | createAudioWorkletNode(
method addAudioWorkletModule (line 376) | async addAudioWorkletModule(url: string): Promise<void> {
method workletsAreReady (line 394) | protected async workletsAreReady(): Promise<void> {
method updateInterval (line 409) | get updateInterval(): Seconds {
method updateInterval (line 412) | set updateInterval(interval: Seconds) {
method clockSource (line 420) | get clockSource(): TickerClockSource {
method clockSource (line 423) | set clockSource(type: TickerClockSource) {
method lookAhead (line 433) | get lookAhead(): Seconds {
method lookAhead (line 436) | set lookAhead(time: Seconds) {
method latencyHint (line 458) | get latencyHint(): ContextLatencyHint | Seconds {
method rawContext (line 465) | get rawContext(): AnyAudioContext {
method now (line 476) | now(): Seconds {
method immediate (line 487) | immediate(): Seconds {
method resume (line 496) | resume(): Promise<void> {
method close (line 508) | async close(): Promise<void> {
method getConstant (line 526) | getConstant(val: number): AudioBufferSourceNode {
method dispose (line 553) | dispose(): this {
method _timeoutLoop (line 572) | private _timeoutLoop(): void {
method setTimeout (line 592) | setTimeout(fn: (...args: any[]) => void, timeout: Seconds): number {
method clearTimeout (line 607) | clearTimeout(id: number): this {
method clearInterval (line 620) | clearInterval(id: number): this {
method setInterval (line 630) | setInterval(fn: (...args: any[]) => void, interval: Seconds): number {
FILE: Tone/core/context/ContextInitialization.ts
function onContextInit (line 14) | function onContextInit(cb: (ctx: Context) => void): void {
function initializeContext (line 21) | function initializeContext(ctx: Context): void {
function onContextClose (line 34) | function onContextClose(cb: (ctx: Context) => void): void {
function closeContext (line 38) | function closeContext(ctx: Context): void {
FILE: Tone/core/context/Delay.ts
type DelayOptions (line 7) | interface DelayOptions extends ToneAudioNodeOptions {
class Delay (line 24) | class Delay extends ToneAudioNode<DelayOptions> {
method constructor (line 56) | constructor() {
method getDefaults (line 86) | static getDefaults(): DelayOptions {
method maxDelay (line 97) | get maxDelay(): Seconds {
method dispose (line 104) | dispose(): this {
FILE: Tone/core/context/Destination.ts
type DestinationOptions (line 13) | interface DestinationOptions extends ToneAudioNodeOptions {
class DestinationInstance (line 35) | class DestinationInstance extends ToneAudioNode<DestinationOptions> {
method constructor (line 55) | constructor() {
method getDefaults (line 76) | static getDefaults(): DestinationOptions {
method mute (line 92) | get mute(): boolean {
method mute (line 95) | set mute(mute: boolean) {
method chain (line 111) | chain(...args: Array<AudioNode | ToneAudioNode>): this {
method maxChannelCount (line 124) | get maxChannelCount(): number {
method dispose (line 131) | dispose(): this {
FILE: Tone/core/context/DummyContext.ts
class DummyContext (line 9) | class DummyContext extends BaseContext {
method createAnalyser (line 13) | createAnalyser(): AnalyserNode {
method createOscillator (line 17) | createOscillator(): OscillatorNode {
method createBufferSource (line 21) | createBufferSource() {
method createBiquadFilter (line 25) | createBiquadFilter(): BiquadFilterNode {
method createBuffer (line 29) | createBuffer(
method createChannelMerger (line 37) | createChannelMerger(
method createChannelSplitter (line 43) | createChannelSplitter(
method createConstantSource (line 49) | createConstantSource(): ConstantSourceNode {
method createConvolver (line 53) | createConvolver(): ConvolverNode {
method createDelay (line 57) | createDelay(_maxDelayTime?: number | undefined): DelayNode {
method createDynamicsCompressor (line 61) | createDynamicsCompressor(): DynamicsCompressorNode {
method createGain (line 65) | createGain(): GainNode {
method createIIRFilter (line 69) | createIIRFilter(
method createPanner (line 76) | createPanner(): PannerNode {
method createPeriodicWave (line 80) | createPeriodicWave(
method createStereoPanner (line 88) | createStereoPanner(): StereoPannerNode {
method createWaveShaper (line 92) | createWaveShaper(): WaveShaperNode {
method createMediaStreamSource (line 96) | createMediaStreamSource(_stream: MediaStream): MediaStreamAudioSourceN...
method createMediaElementSource (line 100) | createMediaElementSource(
method createMediaStreamDestination (line 106) | createMediaStreamDestination(): MediaStreamAudioDestinationNode {
method decodeAudioData (line 110) | decodeAudioData(_audioData: ArrayBuffer): Promise<AudioBuffer> {
method createAudioWorkletNode (line 118) | createAudioWorkletNode(
method rawContext (line 125) | get rawContext(): AnyAudioContext {
method addAudioWorkletModule (line 129) | async addAudioWorkletModule(_url: string): Promise<void> {
method resume (line 137) | resume(): Promise<void> {
method setTimeout (line 141) | setTimeout(_fn: (...args: any[]) => void, _timeout: Seconds): number {
method clearTimeout (line 145) | clearTimeout(_id: number): this {
method setInterval (line 149) | setInterval(_fn: (...args: any[]) => void, _interval: Seconds): number {
method clearInterval (line 153) | clearInterval(_id: number): this {
method getConstant (line 157) | getConstant(_val: number): AudioBufferSourceNode {
method currentTime (line 161) | get currentTime(): Seconds {
method state (line 165) | get state(): AudioContextState {
method sampleRate (line 169) | get sampleRate(): number {
method listener (line 173) | get listener(): Listener {
method transport (line 177) | get transport(): Transport {
method draw (line 181) | get draw(): Draw {
method draw (line 184) | set draw(_d) {}
method destination (line 186) | get destination(): Destination {
method destination (line 189) | set destination(_d: Destination) {}
method now (line 191) | now() {
method immediate (line 195) | immediate() {
FILE: Tone/core/context/Gain.ts
type GainOptions (line 7) | interface GainOptions<TypeName extends UnitName> extends ToneAudioNodeOp...
class Gain (line 28) | class Gain<
method constructor (line 58) | constructor() {
method getDefaults (line 77) | static getDefaults(): GainOptions<any> {
method dispose (line 88) | dispose(): this {
FILE: Tone/core/context/Listener.ts
type ListenerOptions (line 5) | interface ListenerOptions extends ToneAudioNodeOptions {
class ListenerInstance (line 24) | class ListenerInstance extends ToneAudioNode<ListenerOptions> {
method getDefaults (line 78) | static getDefaults(): ListenerOptions {
method dispose (line 92) | dispose(): this {
FILE: Tone/core/context/Offline.ts
function Offline (line 42) | async function Offline(
FILE: Tone/core/context/OfflineContext.ts
class OfflineContext (line 18) | class OfflineContext extends Context {
method constructor (line 45) | constructor() {
method now (line 69) | now(): Seconds {
method currentTime (line 76) | get currentTime(): Seconds {
method _renderClock (line 83) | private async _renderClock(asynchronous: boolean): Promise<void> {
method render (line 105) | async render(asynchronous = true): Promise<ToneAudioBuffer> {
method close (line 115) | close(): Promise<void> {
FILE: Tone/core/context/OnRunning.ts
function onContextRunning (line 9) | function onContextRunning(
FILE: Tone/core/context/Param.test.ts
function matchesOutputCurve (line 57) | function matchesOutputCurve(param, outBuffer): void {
function testUnitConversion (line 384) | function testUnitConversion(
function testMinMaxValue (line 436) | function testMinMaxValue(units: UnitName, min, max): void {
function testSetValueAtTime (line 507) | function testSetValueAtTime(
function testRampToValueAtTime (line 596) | function testRampToValueAtTime(
function testRampToValueAtTime (line 677) | function testRampToValueAtTime(
FILE: Tone/core/context/Param.ts
type ParamOptions (line 19) | interface ParamOptions<TypeName extends UnitName>
type AutomationType (line 33) | type AutomationType =
type TargetAutomationEvent (line 40) | interface TargetAutomationEvent {
type NormalAutomationEvent (line 47) | interface NormalAutomationEvent {
type AutomationEvent (line 55) | type AutomationEvent = NormalAutomationEvent | TargetAutomationEvent;
class Param (line 64) | class Param<TypeName extends UnitName = "number">
method constructor (line 115) | constructor() {
method getDefaults (line 160) | static getDefaults(): ParamOptions<any> {
method value (line 167) | get value(): UnitMap[TypeName] {
method value (line 171) | set value(value) {
method minValue (line 176) | get minValue(): number {
method maxValue (line 201) | get maxValue(): number {
method _is (line 217) | private _is<T>(arg: any, type: UnitName): arg is T {
method _assertRange (line 224) | private _assertRange(value: number): number {
method _fromType (line 239) | protected _fromType(val: UnitMap[TypeName]): number {
method _toType (line 261) | protected _toType(val: number): UnitMap[TypeName] {
method setValueAtTime (line 274) | setValueAtTime(value: UnitMap[TypeName], time: Time): this {
method getValueAtTime (line 292) | getValueAtTime(time: Time): UnitMap[TypeName] {
method setRampPoint (line 358) | setRampPoint(time: Time): this {
method linearRampToValueAtTime (line 369) | linearRampToValueAtTime(value: UnitMap[TypeName], endTime: Time): this {
method exponentialRampToValueAtTime (line 387) | exponentialRampToValueAtTime(
method exponentialRampTo (line 416) | exponentialRampTo(
method linearRampTo (line 430) | linearRampTo(
method targetRampTo (line 444) | targetRampTo(
method exponentialApproachValueAtTime (line 455) | exponentialApproachValueAtTime(
method setTargetAtTime (line 470) | setTargetAtTime(
method setValueCurveAtTime (line 504) | setValueCurveAtTime(
method cancelScheduledValues (line 525) | cancelScheduledValues(time: Time): this {
method cancelAndHoldAtTime (line 537) | cancelAndHoldAtTime(time: Time): this {
method rampTo (line 593) | rampTo(
method apply (line 615) | apply(param: Param | AudioParam): this {
method setParam (line 650) | setParam(param: AudioParam): this {
method dispose (line 663) | dispose(): this {
method defaultValue (line 669) | get defaultValue(): UnitMap[TypeName] {
method _exponentialApproach (line 679) | protected _exponentialApproach(
method _linearInterpolate (line 690) | protected _linearInterpolate(
method _exponentialInterpolate (line 701) | protected _exponentialInterpolate(
FILE: Tone/core/context/ToneAudioBuffer.test.ts
method onload (line 93) | onload(): void {
method onload (line 109) | onload(): void {
FILE: Tone/core/context/ToneAudioBuffer.ts
type ToneAudioBufferOptions (line 9) | interface ToneAudioBufferOptions {
class ToneAudioBuffer (line 26) | class ToneAudioBuffer extends Tone {
method constructor (line 58) | constructor() {
method getDefaults (line 78) | static getDefaults(): ToneAudioBufferOptions {
method sampleRate (line 89) | get sampleRate(): number {
method set (line 100) | set(buffer: AudioBuffer | ToneAudioBuffer): this {
method get (line 125) | get(): AudioBuffer | undefined {
method load (line 135) | async load(url: string): Promise<this> {
method dispose (line 157) | dispose(): this {
method fromArray (line 168) | fromArray(array: Float32Array | Float32Array[]): this {
method toMono (line 192) | toMono(chanNum?: number): this {
method toArray (line 216) | toArray(channel?: number): Float32Array | Float32Array[] {
method getChannelData (line 235) | getChannelData(channel: number): Float32Array {
method slice (line 249) | slice(start: Seconds, end: Seconds = this.duration): ToneAudioBuffer {
method _reverse (line 275) | private _reverse(): this {
method loaded (line 287) | get loaded(): boolean {
method duration (line 294) | get duration(): Seconds {
method length (line 305) | get length(): Samples {
method numberOfChannels (line 316) | get numberOfChannels(): number {
method reverse (line 327) | get reverse(): boolean {
method reverse (line 330) | set reverse(rev: boolean) {
method fromArray (line 352) | static fromArray(array: Float32Array | Float32Array[]): ToneAudioBuffer {
method fromUrl (line 361) | static async fromUrl(url: string): Promise<ToneAudioBuffer> {
method load (line 374) | static async load(url: string): Promise<AudioBuffer> {
method supportsType (line 402) | static supportsType(url: string): boolean {
method loaded (line 414) | static async loaded(): Promise<void> {
FILE: Tone/core/context/ToneAudioBuffers.test.ts
method onload (line 76) | onload(): void {
method onerror (line 89) | onerror(): void {
FILE: Tone/core/context/ToneAudioBuffers.ts
type ToneAudioBuffersUrlMap (line 8) | interface ToneAudioBuffersUrlMap {
type ToneAudioBuffersOptions (line 13) | interface ToneAudioBuffersOptions {
class ToneAudioBuffers (line 45) | class ToneAudioBuffers extends Tone {
method constructor (line 74) | constructor() {
method getDefaults (line 97) | static getDefaults(): ToneAudioBuffersOptions {
method has (line 110) | has(name: string | number): boolean {
method get (line 119) | get(name: string | number): ToneAudioBuffer {
method _bufferLoaded (line 127) | private _bufferLoaded(callback: () => void): void {
method loaded (line 137) | get loaded(): boolean {
method add (line 148) | add(
method dispose (line 175) | dispose(): this {
FILE: Tone/core/context/ToneAudioNode.ts
type InputNode (line 7) | type InputNode = ToneAudioNode | AudioNode | Param<any> | AudioParam;
type OutputNode (line 8) | type OutputNode = ToneAudioNode | AudioNode;
type ChannelProperties (line 10) | interface ChannelProperties {
type ToneAudioNodeOptions (line 19) | type ToneAudioNodeOptions = ToneWithContextOptions;
method numberOfInputs (line 52) | get numberOfInputs(): number {
method numberOfOutputs (line 70) | get numberOfOutputs(): number {
method _isAudioNode (line 90) | private _isAudioNode(node: any): node is AudioNode | ToneAudioNode {
method _getInternalNodes (line 101) | private _getInternalNodes(): OutputNode[] {
method _setChannelProperties (line 119) | private _setChannelProperties(options: ChannelProperties): void {
method _getChannelProperties (line 132) | private _getChannelProperties(): ChannelProperties {
method channelCount (line 153) | get channelCount(): number {
method channelCount (line 156) | set channelCount(channelCount) {
method channelCountMode (line 170) | get channelCountMode(): ChannelCountMode {
method channelCountMode (line 173) | set channelCountMode(channelCountMode) {
method channelInterpretation (line 184) | get channelInterpretation(): ChannelInterpretation {
method channelInterpretation (line 187) | set channelInterpretation(channelInterpretation) {
method connect (line 205) | connect(destination: InputNode, outputNum = 0, inputNum = 0): this {
method toDestination (line 216) | toDestination(): this {
method toMaster (line 226) | toMaster(): this {
method disconnect (line 234) | disconnect(destination?: InputNode, outputNum = 0, inputNum = 0): this {
method chain (line 249) | chain(...nodes: InputNode[]): this {
method fan (line 264) | fan(...nodes: InputNode[]): this {
method dispose (line 272) | dispose(): this {
function connectSeries (line 301) | function connectSeries(...nodes: InputNode[]): void {
function connect (line 321) | function connect(
function disconnect (line 369) | function disconnect(
function fanIn (line 408) | function fanIn(...nodes: OutputNode[]): void {
FILE: Tone/core/context/ToneWithContext.ts
type ToneWithContextOptions (line 27) | interface ToneWithContextOptions {
method constructor (line 54) | constructor() {
method getDefaults (line 68) | static getDefaults(): ToneWithContextOptions {
method now (line 81) | now(): Seconds {
method immediate (line 92) | immediate(): Seconds {
method sampleTime (line 99) | get sampleTime(): Seconds {
method blockTime (line 108) | get blockTime(): Seconds {
method toSeconds (line 121) | toSeconds(time?: Time): Seconds {
method toFrequency (line 132) | toFrequency(freq: Frequency): Hertz {
method toTicks (line 142) | toTicks(time?: Time | TimeClass): Ticks {
method _getPartialProperties (line 153) | protected _getPartialProperties(props: Options): Partial<Options> {
method get (line 170) | get(): Options {
method set (line 215) | set(props: RecursivePartial<Options>): this {
method _onContextRunning (line 247) | protected _onContextRunning(callback: () => void): void {
method dispose (line 254) | dispose(): this {
FILE: Tone/core/type/Conversions.ts
function equalPowerScale (line 14) | function equalPowerScale(percent: NormalRange): number {
function dbToGain (line 22) | function dbToGain(db: Decibels): GainFactor {
function gainToDb (line 29) | function gainToDb(gain: GainFactor): Decibels {
function intervalToFrequencyRatio (line 41) | function intervalToFrequencyRatio(interval: Interval): number {
function getA4 (line 51) | function getA4(): Hertz {
function setA4 (line 55) | function setA4(freq: Hertz): void {
function ftom (line 65) | function ftom(frequency: Hertz): MidiNote {
function ftomf (line 72) | function ftomf(frequency: Hertz): number {
function mtof (line 83) | function mtof(midi: MidiNote): Hertz {
FILE: Tone/core/type/Frequency.ts
type FrequencyUnit (line 16) | type FrequencyUnit = TimeBaseUnit | "midi";
class FrequencyClass (line 27) | class FrequencyClass<Type extends number = Hertz> extends TimeClass<
method A4 (line 39) | static get A4(): Hertz {
method A4 (line 42) | static set A4(freq: Hertz) {
method _getExpressions (line 50) | protected _getExpressions(): TimeExpression<Type> {
method transpose (line 105) | transpose(interval: Interval): FrequencyClass {
method harmonize (line 119) | harmonize(intervals: Interval[]): FrequencyClass[] {
method toMidi (line 134) | toMidi(): MidiNote {
method toNote (line 143) | toNote(): Note {
method toSeconds (line 158) | toSeconds(): Seconds {
method toTicks (line 165) | toTicks(): Ticks {
method _noArg (line 178) | protected _noArg(): Type {
method _frequencyToUnits (line 185) | protected _frequencyToUnits(freq: Hertz): Type {
method _ticksToUnits (line 192) | protected _ticksToUnits(ticks: Ticks): Type {
method _beatsToUnits (line 199) | protected _beatsToUnits(beats: number): Type {
method _secondsToUnits (line 206) | protected _secondsToUnits(seconds: Seconds): Type {
method mtof (line 215) | static mtof(midi: MidiNote): Hertz {
method ftom (line 223) | static ftom(frequency: Hertz): MidiNote {
function Frequency (line 338) | function Frequency(
FILE: Tone/core/type/Midi.ts
class MidiClass (line 13) | class MidiClass extends FrequencyClass<MidiNote> {
method _frequencyToUnits (line 21) | protected _frequencyToUnits(freq: Hertz): MidiNote {
method _ticksToUnits (line 28) | protected _ticksToUnits(ticks: Ticks): MidiNote {
method _beatsToUnits (line 35) | protected _beatsToUnits(beats: number): MidiNote {
method _secondsToUnits (line 42) | protected _secondsToUnits(seconds: Seconds): MidiNote {
method toMidi (line 51) | toMidi(): MidiNote {
method toFrequency (line 60) | toFrequency(): Hertz {
method transpose (line 70) | transpose(interval: Interval): MidiClass {
function Midi (line 79) | function Midi(value?: TimeValue, units?: FrequencyUnit): MidiClass {
FILE: Tone/core/type/NoteUnits.ts
type Letter (line 3) | type Letter = "C" | "D" | "E" | "F" | "G" | "A" | "B";
type Accidental (line 4) | type Accidental = "bb" | "b" | "" | "#" | "x";
type Octave (line 5) | type Octave =
type Note (line 29) | type Note = `${Letter}${Accidental}${Octave}`;
type IntegerRange (line 31) | type IntegerRange<
type MidiNote (line 40) | type MidiNote = IntegerRange<128>;
FILE: Tone/core/type/Ticks.ts
class TicksClass (line 14) | class TicksClass extends TransportTimeClass<Ticks> {
method _now (line 22) | protected _now(): Ticks {
method _beatsToUnits (line 29) | protected _beatsToUnits(beats: number): Ticks {
method _secondsToUnits (line 36) | protected _secondsToUnits(seconds: Seconds): Ticks {
method _ticksToUnits (line 43) | protected _ticksToUnits(ticks: Ticks): Ticks {
method toTicks (line 50) | toTicks(): Ticks {
method toSeconds (line 57) | toSeconds(): Seconds {
function Ticks (line 66) | function Ticks(value?: TimeValue, units?: TimeBaseUnit): TicksClass {
FILE: Tone/core/type/Time.ts
class TimeClass (line 27) | class TimeClass<
method _getExpressions (line 33) | protected _getExpressions(): TimeExpression<Type> {
method quantize (line 70) | quantize(subdiv: Time, percent = 1): Type {
method toNotation (line 93) | toNotation(): Subdivision {
method toBarsBeatsSixteenths (line 128) | toBarsBeatsSixteenths(): BarsBeatsSixteenths {
method toTicks (line 147) | toTicks(): Ticks {
method toSeconds (line 156) | toSeconds(): Seconds {
method toMidi (line 163) | toMidi(): MidiNote {
method _now (line 167) | protected _now(): Type {
function Time (line 188) | function Time(
FILE: Tone/core/type/TimeBase.ts
type TimeValue (line 15) | type TimeValue = Time | TimeBaseClass<any, any>;
type TimeBaseUnit (line 20) | type TimeBaseUnit =
type TypeFunction (line 31) | interface TypeFunction {
type TimeExpression (line 36) | interface TimeExpression<Type extends number> {
method constructor (line 78) | constructor(context: BaseContext, value?: TimeValue, units?: Unit) {
method _getExpressions (line 90) | protected _getExpressions(): TimeExpression<Type> {
method valueOf (line 185) | valueOf(): Type {
method _frequencyToUnits (line 234) | protected _frequencyToUnits(freq: Hertz): Type {
method _beatsToUnits (line 241) | protected _beatsToUnits(beats: number): Type {
method _secondsToUnits (line 248) | protected _secondsToUnits(seconds: Seconds): Type {
method _ticksToUnits (line 255) | protected _ticksToUnits(ticks: Ticks): Type {
method _noArg (line 262) | protected _noArg(): Type {
method _getBpm (line 273) | protected _getBpm(): BPM {
method _getTimeSignature (line 280) | protected _getTimeSignature(): number {
method _getPPQ (line 287) | protected _getPPQ(): number {
method fromType (line 304) | fromType(type: TimeBaseClass<any, any>): this {
method toFrequency (line 341) | toFrequency(): Hertz {
method toSamples (line 348) | toSamples(): Samples {
method toMilliseconds (line 355) | toMilliseconds(): Milliseconds {
FILE: Tone/core/type/TransportTime.ts
class TransportTimeClass (line 13) | class TransportTimeClass<
method _now (line 21) | protected _now(): Type {
function TransportTime (line 33) | function TransportTime(
FILE: Tone/core/type/Units.ts
type Seconds (line 9) | type Seconds = number;
type Decibels (line 15) | type Decibels = number;
type NormalRange (line 21) | type NormalRange = number;
type AudioRange (line 27) | type AudioRange = number;
type Interval (line 33) | type Interval = number;
type GainFactor (line 39) | type GainFactor = number;
type Positive (line 45) | type Positive = number;
type Subdivision (line 53) | type Subdivision =
type TimeObject (line 68) | type TimeObject = {
type Time (line 83) | type Time = string | Seconds | TimeObject | Subdivision;
type Frequency (line 94) | type Frequency = Subdivision | Note | string | Hertz;
type TimeSignature (line 100) | type TimeSignature = number | number[];
type TransportTime (line 109) | type TransportTime = Time;
type Ticks (line 116) | type Ticks = number;
type BPM (line 122) | type BPM = number;
type Degrees (line 128) | type Degrees = number;
type Radians (line 134) | type Radians = number;
type BarsBeatsSixteenths (line 141) | type BarsBeatsSixteenths = `${number}:${number}:${number}`;
type Samples (line 147) | type Samples = number;
type Hertz (line 153) | type Hertz = number;
type Cents (line 160) | type Cents = number;
type Milliseconds (line 166) | type Milliseconds = number;
type PowerOfTwo (line 172) | type PowerOfTwo = number;
type UnitMap (line 177) | interface UnitMap {
type Unit (line 200) | type Unit = UnitMap[keyof UnitMap];
type UnitName (line 206) | type UnitName = keyof UnitMap;
FILE: Tone/core/util/AdvancedTypeCheck.ts
function isAudioParam (line 12) | function isAudioParam(arg: any): arg is AudioParam {
function isAudioNode (line 19) | function isAudioNode(arg: any): arg is AudioNode {
function isOfflineAudioContext (line 26) | function isOfflineAudioContext(arg: any): arg is OfflineAudioContext {
function isAudioContext (line 33) | function isAudioContext(arg: any): arg is AudioContext {
function isAudioBuffer (line 40) | function isAudioBuffer(arg: any): arg is AudioBuffer {
FILE: Tone/core/util/Debug.ts
function assert (line 10) | function assert(statement: boolean, error: string): asserts statement {
function assertRange (line 19) | function assertRange(value: number, gte: number, lte = Infinity): void {
function assertContextRunning (line 30) | function assertContextRunning(context: BaseContext): void {
function enterScheduledCallback (line 48) | function enterScheduledCallback(insideCallback: boolean): void {
function assertUsedScheduleTime (line 55) | function assertUsedScheduleTime(time?: Time): void {
type Logger (line 71) | interface Logger {
function setLogger (line 84) | function setLogger(logger: Logger): void {
function log (line 91) | function log(...args: any[]): void {
function warn (line 98) | function warn(...args: any[]): void {
FILE: Tone/core/util/Decorator.ts
function range (line 7) | function range(min: number, max = Infinity) {
function timeRange (line 28) | function timeRange(min: number, max = Infinity) {
FILE: Tone/core/util/Defaults.ts
function noCopy (line 12) | function noCopy(key: string, arg: any): boolean {
function deepMerge (line 39) | function deepMerge(target: any, ...sources: any[]): any {
function deepEquals (line 66) | function deepEquals<T>(arrayA: T[], arrayB: T[]): boolean {
function optionsFromArguments (line 77) | function optionsFromArguments<T extends object>(
function getDefaultsFromInstance (line 115) | function getDefaultsFromInstance<T>(instance: T): BaseToneOptions {
function defaultArg (line 129) | function defaultArg<T>(given: T, fallback: T): T {
function omitFromObject (line 140) | function omitFromObject<T extends object, O extends string[]>(
FILE: Tone/core/util/Draw.ts
type DrawEvent (line 12) | interface DrawEvent extends TimelineEvent {
class DrawInstance (line 34) | class DrawInstance extends ToneWithContext<ToneWithContextOptions> {
method schedule (line 75) | schedule(callback: () => void, time: Time): this {
method cancel (line 91) | cancel(after?: Time): this {
method _drawLoop (line 99) | private _drawLoop(): void {
method dispose (line 112) | dispose(): this {
FILE: Tone/core/util/Emitter.ts
type EmitterEventObject (line 4) | interface EmitterEventObject {
class Emitter (line 14) | class Emitter<EventType extends string = string> extends Tone {
method on (line 27) | on(event: EventType, callback: (...args: any[]) => void): this {
method once (line 47) | once(event: EventType, callback: (...args: any[]) => void): this {
method off (line 64) | off(event: EventType, callback?: (...args: any[]) => void): this {
method emit (line 92) | emit(event: EventType, ...args: any[]): this {
method mixin (line 107) | static mixin(constr: any): void {
method dispose (line 121) | dispose(): this {
FILE: Tone/core/util/Interface.ts
type Omit (line 4) | type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
function readOnly (line 9) | function readOnly<T extends object>(
function writable (line 26) | function writable<T extends object>(
type RecursivePartial (line 46) | type RecursivePartial<T> = {
FILE: Tone/core/util/IntervalTimeline.ts
type IntervalTimelineEvent (line 8) | interface IntervalTimelineEvent {
type IteratorCallback (line 14) | type IteratorCallback = (event: IntervalTimelineEvent) => void;
class IntervalTimeline (line 25) | class IntervalTimeline extends Tone {
method add (line 43) | add(event: IntervalTimelineEvent): this {
method remove (line 76) | remove(event: IntervalTimelineEvent): this {
method length (line 95) | get length(): number {
method cancel (line 103) | cancel(after: number): this {
method _setRoot (line 111) | private _setRoot(node: IntervalNode | null): void {
method _replaceNodeInParent (line 122) | private _replaceNodeInParent(
method _removeNode (line 142) | private _removeNode(node: IntervalNode): void {
method _rotateLeft (line 205) | private _rotateLeft(node: IntervalNode): void {
method _rotateRight (line 230) | private _rotateRight(node: IntervalNode): void {
method _rebalance (line 255) | private _rebalance(node: IntervalNode): void {
method get (line 277) | get(time: number): IntervalTimelineEvent | null {
method forEach (line 298) | forEach(callback: IteratorCallback): this {
method forEachAtTime (line 317) | forEachAtTime(time: number, callback: IteratorCallback): this {
method forEachFrom (line 336) | forEachFrom(time: number, callback: IteratorCallback): this {
method dispose (line 352) | dispose(): this {
class IntervalNode (line 376) | class IntervalNode {
method constructor (line 394) | constructor(low: number, high: number, event: IntervalTimelineEvent) {
method insert (line 407) | insert(node: IntervalNode): void {
method search (line 427) | search(point: number, results: IntervalNode[]): void {
method searchAfter (line 458) | searchAfter(point: number, results: IntervalNode[]): void {
method traverse (line 476) | traverse(callback: (self: IntervalNode) => void): void {
method updateHeight (line 489) | updateHeight(): void {
method updateMax (line 504) | updateMax(): void {
method getBalance (line 518) | getBalance(): number {
method isLeftChild (line 533) | isLeftChild(): boolean {
method left (line 540) | get left(): IntervalNode | null {
method left (line 544) | set left(node: IntervalNode | null) {
method right (line 556) | get right(): IntervalNode | null {
method right (line 560) | set right(node: IntervalNode | null) {
method dispose (line 572) | dispose(): void {
FILE: Tone/core/util/Math.ts
constant EPSILON (line 5) | const EPSILON = 1e-6;
function GT (line 10) | function GT(a: number, b: number): boolean {
function GTE (line 17) | function GTE(a: number, b: number): boolean {
function LT (line 24) | function LT(a: number, b: number): boolean {
function EQ (line 31) | function EQ(a: number, b: number): boolean {
function clamp (line 38) | function clamp(value: number, min: number, max: number): number {
FILE: Tone/core/util/StateTimeline.ts
type BasicPlaybackState (line 5) | type BasicPlaybackState = "started" | "stopped";
type PlaybackState (line 6) | type PlaybackState = BasicPlaybackState | "paused";
type StateTimelineEvent (line 8) | interface StateTimelineEvent extends TimelineEvent {
class StateTimeline (line 17) | class StateTimeline<
method constructor (line 27) | constructor(initial: PlaybackState = "stopped") {
method getValueAtTime (line 39) | getValueAtTime(time: Seconds): PlaybackState {
method setStateAtTime (line 54) | setStateAtTime(
method getLastState (line 75) | getLastState(
method getNextState (line 95) | getNextState(
FILE: Tone/core/util/Timeline.test.ts
type StateTimelineEvent (line 5) | interface StateTimelineEvent {
type TimelineNameEvent (line 10) | interface TimelineNameEvent {
type TimelineValueEvent (line 15) | interface TimelineValueEvent {
type AddedInterface (line 537) | interface AddedInterface {
FILE: Tone/core/util/Timeline.ts
type TimelineSearchParam (line 7) | type TimelineSearchParam = "ticks" | "time";
type TimelineOptions (line 12) | interface TimelineOptions {
type TimelineEvent (line 20) | interface TimelineEvent {
class Timeline (line 31) | class Timeline<GenericEvent extends TimelineEvent> extends Tone {
method constructor (line 56) | constructor() {
method getDefaults (line 68) | static getDefaults(): TimelineOptions {
method length (line 78) | get length(): number {
method add (line 86) | add(event: GenericEvent): this {
method remove (line 117) | remove(event: GenericEvent): this {
method get (line 129) | get(
method peek (line 146) | peek(): GenericEvent | undefined {
method shift (line 154) | shift(): GenericEvent | undefined {
method getAfter (line 162) | getAfter(
method getBefore (line 178) | getBefore(time: number): GenericEvent | null {
method cancel (line 196) | cancel(after: number): this {
method cancelBefore (line 229) | cancelBefore(time: number): this {
method previousEvent (line 242) | previousEvent(event: GenericEvent): GenericEvent | null {
method _search (line 257) | protected _search(
method _iterate (line 303) | private _iterate(
method forEach (line 315) | forEach(callback: (event: GenericEvent) => void): this {
method forEachBefore (line 325) | forEachBefore(
method forEachAfter (line 342) | forEachAfter(time: Seconds, callback: (event: GenericEvent) => void): ...
method forEachBetween (line 357) | forEachBetween(
method forEachFrom (line 385) | forEachFrom(time: number, callback: (event: GenericEvent) => void): th...
method forEachAtTime (line 401) | forEachAtTime(time: number, callback: (event: GenericEvent) => void): ...
method dispose (line 427) | dispose(): this {
FILE: Tone/core/util/TimelineValue.ts
type TimelineValueEvent (line 5) | interface TimelineValueEvent<T> extends TimelineEvent {
class TimelineValue (line 12) | class TimelineValue<Type> extends Tone {
method constructor (line 30) | constructor(initialValue: Type) {
method set (line 38) | set(value: Type, time: Seconds): this {
method get (line 49) | get(time: Seconds): Type {
FILE: Tone/core/util/TypeCheck.ts
function isUndef (line 6) | function isUndef(arg: unknown): arg is undefined {
function isDefined (line 13) | function isDefined<T>(arg: T | undefined): arg is T {
function isFunction (line 20) | function isFunction(arg: unknown): arg is (a: any) => any {
function isNumber (line 27) | function isNumber(arg: unknown): arg is number {
function isObject (line 34) | function isObject(arg: unknown): arg is object {
function isBoolean (line 44) | function isBoolean(arg: unknown): arg is boolean {
function isArray (line 51) | function isArray(arg: unknown): arg is any[] {
function isString (line 58) | function isString(arg: unknown): arg is string {
function isNote (line 66) | function isNote(arg: unknown): arg is Note {
FILE: Tone/core/util/global.d.ts
type AudioParamMap (line 5) | interface AudioParamMap extends Map<string, AudioParam> {
FILE: Tone/core/worklet/ToneAudioWorklet.ts
type ToneAudioWorkletOptions (line 8) | interface ToneAudioWorkletOptions extends ToneAudioNodeOptions {
method constructor (line 51) | constructor(options: Options) {
method dispose (line 96) | dispose(): this {
FILE: Tone/core/worklet/WorkletGlobalScope.ts
function addToWorklet (line 9) | function addToWorklet(classOrFunction: string) {
function registerProcessor (line 16) | function registerProcessor(name: string, classDesc: string) {
function getWorkletGlobalScope (line 24) | function getWorkletGlobalScope(): string {
FILE: Tone/effect/AutoFilter.ts
type AutoFilterOptions (line 7) | interface AutoFilterOptions extends LFOEffectOptions {
class AutoFilter (line 28) | class AutoFilter extends LFOEffect<AutoFilterOptions> {
method constructor (line 52) | constructor() {
method getDefaults (line 73) | static getDefaults(): AutoFilterOptions {
method baseFrequency (line 88) | get baseFrequency(): Frequency {
method baseFrequency (line 91) | set baseFrequency(freq) {
method octaves (line 100) | get octaves(): Positive {
method octaves (line 103) | set octaves(oct) {
method dispose (line 108) | dispose(): this {
FILE: Tone/effect/AutoPanner.ts
type AutoPannerOptions (line 6) | interface AutoPannerOptions extends LFOEffectOptions {
class AutoPanner (line 21) | class AutoPanner extends LFOEffect<AutoPannerOptions> {
method constructor (line 34) | constructor() {
method getDefaults (line 53) | static getDefaults(): AutoPannerOptions {
method dispose (line 59) | dispose(): this {
FILE: Tone/effect/AutoWah.ts
type AutoWahOptions (line 19) | interface AutoWahOptions extends EffectOptions {
class AutoWah (line 43) | class AutoWah extends Effect<AutoWahOptions> {
method constructor (line 103) | constructor() {
method getDefaults (line 155) | static getDefaults(): AutoWahOptions {
method octaves (line 169) | get octaves() {
method octaves (line 172) | set octaves(octaves) {
method follower (line 180) | get follower(): Time {
method follower (line 183) | set follower(follower) {
method baseFrequency (line 190) | get baseFrequency(): Frequency {
method baseFrequency (line 193) | set baseFrequency(baseFreq) {
method sensitivity (line 201) | get sensitivity(): Decibels {
method sensitivity (line 204) | set sensitivity(sensitivity) {
method _setSweepRange (line 211) | private _setSweepRange() {
method dispose (line 219) | dispose(): this {
FILE: Tone/effect/BitCrusher.ts
type BitCrusherOptions (line 13) | interface BitCrusherOptions extends EffectOptions {
class BitCrusher (line 29) | class BitCrusher extends Effect<BitCrusherOptions> {
method constructor (line 46) | constructor() {
method getDefaults (line 64) | static getDefaults(): BitCrusherOptions {
method dispose (line 70) | dispose(): this {
type BitCrusherWorkletOptions (line 77) | interface BitCrusherWorkletOptions extends ToneAudioWorkletOptions {
class BitCrusherWorklet (line 84) | class BitCrusherWorklet extends ToneAudioWorklet<BitCrusherWorkletOption...
method constructor (line 93) | constructor() {
method getDefaults (line 114) | static getDefaults(): BitCrusherWorkletOptions {
method _audioWorkletName (line 120) | protected _audioWorkletName(): string {
method onReady (line 124) | onReady(node: AudioWorkletNode) {
method dispose (line 130) | dispose(): this {
FILE: Tone/effect/Chebyshev.ts
type ChebyshevOptions (line 7) | interface ChebyshevOptions extends EffectOptions {
class Chebyshev (line 26) | class Chebyshev extends Effect<ChebyshevOptions> {
method constructor (line 44) | constructor() {
method getDefaults (line 63) | static getDefaults(): ChebyshevOptions {
method _getCoefficient (line 76) | private _getCoefficient(
method order (line 107) | get order(): Positive {
method order (line 110) | set order(order) {
method oversample (line 121) | get oversample(): OverSampleType {
method oversample (line 124) | set oversample(oversampling) {
method dispose (line 128) | dispose(): this {
FILE: Tone/effect/Chorus.ts
type ChorusOptions (line 20) | interface ChorusOptions extends StereoFeedbackEffectOptions {
class Chorus (line 41) | class Chorus extends StereoFeedbackEffect<ChorusOptions> {
method constructor (line 90) | constructor() {
method getDefaults (line 132) | static getDefaults(): ChorusOptions {
method depth (line 148) | get depth(): NormalRange {
method depth (line 151) | set depth(depth) {
method delayTime (line 165) | get delayTime(): Milliseconds {
method delayTime (line 168) | set delayTime(delayTime) {
method type (line 176) | get type(): ToneOscillatorType {
method type (line 179) | set type(type) {
method spread (line 188) | get spread(): Degrees {
method spread (line 191) | set spread(spread) {
method start (line 199) | start(time?: Time): this {
method stop (line 208) | stop(time?: Time): this {
method sync (line 218) | sync(): this {
method unsync (line 227) | unsync(): this {
method dispose (line 233) | dispose(): this {
FILE: Tone/effect/Distortion.ts
type DistortionOptions (line 5) | interface DistortionOptions extends EffectOptions {
class Distortion (line 20) | class Distortion extends Effect<DistortionOptions> {
method constructor (line 38) | constructor() {
method getDefaults (line 58) | static getDefaults(): DistortionOptions {
method distortion (line 68) | get distortion(): number {
method distortion (line 71) | set distortion(amount) {
method oversample (line 88) | get oversample(): OverSampleType {
method oversample (line 91) | set oversample(oversampling) {
method dispose (line 95) | dispose(): this {
FILE: Tone/effect/Effect.ts
type EffectOptions (line 11) | interface EffectOptions extends ToneAudioNodeOptions {
method constructor (line 56) | constructor(options: EffectOptions) {
method getDefaults (line 67) | static getDefaults(): EffectOptions {
method connectEffect (line 76) | protected connectEffect(effect: ToneAudioNode | AudioNode): this {
method dispose (line 83) | dispose(): this {
FILE: Tone/effect/FeedbackDelay.ts
type FeedbackDelayOptions (line 8) | interface FeedbackDelayOptions extends FeedbackEffectOptions {
class FeedbackDelay (line 27) | class FeedbackDelay extends FeedbackEffect<FeedbackDelayOptions> {
method constructor (line 42) | constructor() {
method getDefaults (line 62) | static getDefaults(): FeedbackDelayOptions {
method dispose (line 69) | dispose(): this {
FILE: Tone/effect/FeedbackEffect.ts
type FeedbackEffectOptions (line 7) | interface FeedbackEffectOptions extends EffectOptions {
method constructor (line 42) | constructor(options: FeedbackEffectOptions) {
method getDefaults (line 58) | static getDefaults(): FeedbackEffectOptions {
method dispose (line 64) | dispose(): this {
FILE: Tone/effect/Freeverb.ts
type FreeverbOptions (line 8) | interface FreeverbOptions extends StereoEffectOptions {
class Freeverb (line 44) | class Freeverb extends StereoEffect<FreeverbOptions> {
method constructor (line 73) | constructor() {
method getDefaults (line 122) | static getDefaults(): FreeverbOptions {
method dampening (line 133) | get dampening(): Frequency {
method dampening (line 136) | set dampening(d) {
method dispose (line 140) | dispose(): this {
FILE: Tone/effect/FrequencyShifter.ts
type FrequencyShifterOptions (line 12) | interface FrequencyShifterOptions extends EffectOptions {
class FrequencyShifter (line 34) | class FrequencyShifter extends Effect<FrequencyShifterOptions> {
method constructor (line 83) | constructor() {
method getDefaults (line 141) | static getDefaults(): FrequencyShifterOptions {
method dispose (line 147) | dispose(): this {
FILE: Tone/effect/JCReverb.ts
type JCReverbOptions (line 9) | interface JCReverbOptions extends StereoEffectOptions {
class JCReverb (line 47) | class JCReverb extends StereoEffect<JCReverbOptions> {
method constructor (line 75) | constructor() {
method getDefaults (line 125) | static getDefaults(): JCReverbOptions {
method dispose (line 131) | dispose(): this {
FILE: Tone/effect/LFOEffect.ts
type LFOEffectOptions (line 9) | interface LFOEffectOptions extends EffectOptions {
method constructor (line 39) | constructor(options: LFOEffectOptions) {
method getDefaults (line 54) | static getDefaults(): LFOEffectOptions {
method start (line 65) | start(time?: Time): this {
method stop (line 73) | stop(time?: Time): this {
method sync (line 82) | sync(): this {
method unsync (line 90) | unsync(): this {
method type (line 103) | get type() {
method type (line 106) | set type(type) {
method dispose (line 110) | dispose(): this {
FILE: Tone/effect/LFOStereoEffect.test.ts
class LFOStereoEffectTest (line 8) | class LFOStereoEffectTest extends LFOStereoEffect<LFOStereoEffectOptions> {
method getLfoState (line 9) | getLfoState() {
FILE: Tone/effect/LFOStereoEffect.ts
type LFOStereoEffectOptions (line 9) | interface LFOStereoEffectOptions extends StereoEffectOptions {
method constructor (line 40) | constructor() {
method getDefaults (line 73) | static getDefaults(): LFOStereoEffectOptions {
method start (line 83) | start(time?: Time): this {
method stop (line 92) | stop(time?: Time): this {
method sync (line 101) | sync(): this {
method unsync (line 111) | unsync(): this {
method type (line 121) | get type(): ToneOscillatorType {
method type (line 124) | set type(type) {
method dispose (line 129) | dispose(): this {
FILE: Tone/effect/MidSideEffect.ts
type MidSideEffectOptions (line 6) | type MidSideEffectOptions = EffectOptions;
method constructor (line 53) | constructor(options: MidSideEffectOptions) {
method connectEffectMid (line 71) | protected connectEffectMid(...nodes: OutputNode[]): void {
method connectEffectSide (line 78) | protected connectEffectSide(...nodes: OutputNode[]): void {
method dispose (line 82) | dispose(): this {
FILE: Tone/effect/Phaser.ts
type PhaserOptions (line 8) | interface PhaserOptions extends LFOStereoEffectOptions {
class Phaser (line 30) | class Phaser extends LFOStereoEffect<PhaserOptions> {
method constructor (line 69) | constructor() {
method getDefaults (line 99) | static getDefaults(): PhaserOptions {
method _makeFilters (line 110) | private _makeFilters(
method octaves (line 129) | get octaves() {
method octaves (line 132) | set octaves(octaves) {
method baseFrequency (line 142) | get baseFrequency(): Frequency {
method baseFrequency (line 145) | set baseFrequency(freq) {
method dispose (line 152) | dispose(): this {
FILE: Tone/effect/PingPongDelay.ts
type PingPongDelayOptions (line 11) | interface PingPongDelayOptions extends StereoXFeedbackEffectOptions {
class PingPongDelay (line 30) | class PingPongDelay extends StereoXFeedbackEffect<PingPongDelayOptions> {
method constructor (line 59) | constructor() {
method getDefaults (line 99) | static getDefaults(): PingPongDelayOptions {
method dispose (line 106) | dispose(): this {
FILE: Tone/effect/PitchShift.ts
type PitchShiftOptions (line 12) | interface PitchShiftOptions extends FeedbackEffectOptions {
class PitchShift (line 26) | class PitchShift extends FeedbackEffect<PitchShiftOptions> {
method constructor (line 90) | constructor() {
method getDefaults (line 162) | static getDefaults(): PitchShiftOptions {
method pitch (line 179) | get pitch() {
method pitch (line 182) | set pitch(interval) {
method windowSize (line 207) | get windowSize(): Seconds {
method windowSize (line 210) | set windowSize(size) {
method dispose (line 215) | dispose(): this {
FILE: Tone/effect/Reverb.ts
type ReverbOptions (line 11) | interface ReverbOptions extends EffectOptions {
class Reverb (line 28) | class Reverb extends Effect<ReverbOptions> {
method constructor (line 58) | constructor() {
method getDefaults (line 77) | static getDefaults(): ReverbOptions {
method decay (line 87) | get decay(): Time {
method decay (line 90) | set decay(time) {
method preDelay (line 100) | get preDelay(): Time {
method preDelay (line 103) | set preDelay(time) {
method generate (line 114) | async generate(): Promise<this> {
method dispose (line 154) | dispose(): this {
FILE: Tone/effect/ReverseDelay.ts
type ReverseDelayOptions (line 14) | interface ReverseDelayOptions extends EffectOptions {
class ReverseDelay (line 29) | class ReverseDelay extends Effect<ReverseDelayOptions> {
method constructor (line 43) | constructor() {
method _connectWorklet (line 57) | private _connectWorklet(
method delayTime (line 74) | get delayTime(): Time {
method delayTime (line 78) | set delayTime(delayTime) {
method feedback (line 96) | get feedback(): NormalRange {
method feedback (line 100) | set feedback(feedback) {
method getDefaults (line 104) | static getDefaults(): ReverseDelayOptions {
method dispose (line 112) | dispose(): this {
type ReverseDelayWorkletOptions (line 119) | interface ReverseDelayWorkletOptions extends ToneAudioWorkletOptions {
class ReverseDelayWorklet (line 127) | class ReverseDelayWorklet extends ToneAudioWorklet<ReverseDelayWorkletOp...
method constructor (line 137) | constructor() {
method getDefaults (line 168) | static getDefaults(): ReverseDelayWorkletOptions {
method _audioWorkletName (line 175) | protected _audioWorkletName(): string {
method onReady (line 179) | onReady(node: AudioWorkletNode): void {
method dispose (line 185) | dispose(): this {
FILE: Tone/effect/StereoEffect.ts
type StereoEffectOptions (line 15) | type StereoEffectOptions = EffectOptions;
class StereoEffect (line 20) | class StereoEffect<
method constructor (line 49) | constructor(options: StereoEffectOptions) {
method connectEffectLeft (line 76) | protected connectEffectLeft(...nodes: OutputNode[]): void {
method connectEffectRight (line 85) | protected connectEffectRight(...nodes: OutputNode[]): void {
method getDefaults (line 91) | static getDefaults(): StereoEffectOptions {
method dispose (line 97) | dispose(): this {
FILE: Tone/effect/StereoFeedbackEffect.ts
type StereoFeedbackEffectOptions (line 9) | interface StereoFeedbackEffectOptions extends StereoEffectOptions {
class StereoFeedbackEffect (line 16) | class StereoFeedbackEffect<
method constructor (line 46) | constructor(options: StereoFeedbackEffectOptions) {
method getDefaults (line 76) | static getDefaults(): StereoFeedbackEffectOptions {
method dispose (line 82) | dispose(): this {
FILE: Tone/effect/StereoWidener.ts
type StereoWidenerOptions (line 13) | interface StereoWidenerOptions extends MidSideEffectOptions {
class StereoWidener (line 27) | class StereoWidener extends MidSideEffect<StereoWidenerOptions> {
method constructor (line 70) | constructor() {
method getDefaults (line 111) | static getDefaults(): StereoWidenerOptions {
method dispose (line 117) | dispose(): this {
FILE: Tone/effect/StereoXFeedbackEffect.ts
type StereoXFeedbackEffectOptions (line 8) | interface StereoXFeedbackEffectOptions
class StereoXFeedbackEffect (line 26) | class StereoXFeedbackEffect<
method constructor (line 29) | constructor(options: StereoXFeedbackEffectOptions) {
FILE: Tone/effect/Tremolo.ts
type TremoloOptions (line 9) | interface TremoloOptions extends LFOStereoEffectOptions {
class Tremolo (line 28) | class Tremolo extends LFOStereoEffect<TremoloOptions> {
method constructor (line 54) | constructor() {
method getDefaults (line 86) | static getDefaults(): TremoloOptions {
method type (line 98) | get type(): ToneOscillatorType {
method type (line 101) | set type(type) {
method spread (line 110) | get spread(): Degrees {
method spread (line 113) | set spread(spread) {
method dispose (line 118) | dispose(): this {
FILE: Tone/effect/Vibrato.ts
type VibratoOptions (line 11) | interface VibratoOptions extends EffectOptions {
class Vibrato (line 22) | class Vibrato extends Effect<VibratoOptions> {
method constructor (line 50) | constructor() {
method getDefaults (line 82) | static getDefaults(): VibratoOptions {
method type (line 94) | get type(): ToneOscillatorType {
method type (line 97) | set type(type) {
method dispose (line 101) | dispose(): this {
FILE: Tone/event/Loop.ts
type LoopOptions (line 17) | interface LoopOptions extends ToneWithContextOptions {
class Loop (line 40) | class Loop<
method constructor (line 61) | constructor() {
method getDefaults (line 83) | static getDefaults(): LoopOptions {
method start (line 99) | start(time?: TransportTime): this {
method stop (line 108) | stop(time?: TransportTime): this {
method cancel (line 117) | cancel(time?: TransportTime): this {
method _tick (line 126) | protected _tick(time: Seconds): void {
method state (line 133) | get state(): BasicPlaybackState {
method progress (line 140) | get progress(): NormalRange {
method interval (line 150) | get interval(): Time {
method interval (line 153) | set interval(interval) {
method playbackRate (line 161) | get playbackRate(): Positive {
method playbackRate (line 164) | set playbackRate(rate) {
method humanize (line 172) | get humanize(): boolean | Time {
method humanize (line 175) | set humanize(variation) {
method probability (line 182) | get probability(): NormalRange {
method probability (line 186) | set probability(prob) {
method mute (line 193) | get mute(): boolean {
method mute (line 197) | set mute(mute) {
method iterations (line 204) | get iterations(): number {
method iterations (line 211) | set iterations(iters) {
method dispose (line 219) | dispose(): this {
FILE: Tone/event/Part.test.ts
method callback (line 410) | callback(time, value): void {
method callback (line 485) | callback(): void {
method callback (line 504) | callback(): void {
method callback (line 524) | callback(): void {
method callback (line 542) | callback(time): void {
method callback (line 566) | callback(time, value): void {
method callback (line 592) | callback(time, value): void {
method callback (line 614) | callback(): void {
method callback (line 629) | callback(time): void {
method callback (line 648) | callback(): void {
method callback (line 664) | callback(): void {
method callback (line 680) | callback(): void {
method callback (line 702) | callback(time, value): void {
method callback (line 735) | callback(time, value): void {
method callback (line 774) | callback(time, value): void {
method callback (line 801) | callback(): void {
method callback (line 884) | callback(time): void {
method callback (line 906) | callback(time): void {
FILE: Tone/event/Part.ts
type CallbackType (line 21) | type CallbackType<T> = T extends {
type PartOptions (line 32) | interface PartOptions<T>
class Part (line 60) | class Part<ValueType = any> extends ToneEvent<ValueType> {
method constructor (line 85) | constructor() {
method getDefaults (line 105) | static getDefaults(): PartOptions<any> {
method start (line 116) | start(time?: TransportTime, offset?: Time): this {
method _startNote (line 146) | private _startNote(event: ToneEvent, ticks: Ticks, offset: Ticks): void {
method startOffset (line 170) | get startOffset(): Ticks {
method startOffset (line 173) | set startOffset(offset) {
method stop (line 184) | stop(time?: TransportTime): this {
method at (line 208) | at(time: Time, value?: any): ToneEvent | null {
method add (line 248) | add(time: Time | object, value?: any): this {
method _restartEvent (line 289) | private _restartEvent(event: ToneEvent): void {
method remove (line 308) | remove(time: Time | object, value?: any): this {
method clear (line 332) | clear(): this {
method cancel (line 342) | cancel(after?: TransportTime | TransportTimeClass): this {
method _forEach (line 351) | private _forEach(callback: (event: ToneEvent) => void): this {
method _setAll (line 369) | private _setAll(attr: string, value: any): void {
method _tick (line 379) | protected _tick(time: Seconds, value?: any): void {
method _testLoopBoundaries (line 390) | private _testLoopBoundaries(event: ToneEvent): void {
method probability (line 403) | get probability(): NormalRange {
method probability (line 406) | set probability(prob) {
method humanize (line 411) | get humanize(): boolean | Time {
method humanize (line 414) | set humanize(variation) {
method loop (line 433) | get loop(): boolean | number {
method loop (line 436) | set loop(loop) {
method loopEnd (line 450) | get loopEnd(): Time {
method loopEnd (line 453) | set loopEnd(loopEnd) {
method loopStart (line 467) | get loopStart(): Time {
method loopStart (line 470) | set loopStart(loopStart) {
method playbackRate (line 483) | get playbackRate(): Positive {
method playbackRate (line 486) | set playbackRate(rate) {
method length (line 494) | get length(): number {
method dispose (line 498) | dispose(): this {
FILE: Tone/event/Pattern.ts
type PatternOptions (line 8) | interface PatternOptions<ValueType> extends LoopOptions {
class Pattern (line 23) | class Pattern<ValueType> extends Loop<PatternOptions<ValueType>> {
method constructor (line 67) | constructor() {
method getDefaults (line 84) | static getDefaults(): PatternOptions<any> {
method _tick (line 95) | protected _tick(time: Seconds): void {
method values (line 105) | get values(): ValueType[] {
method values (line 108) | set values(val) {
method value (line 117) | get value(): ValueType | undefined {
method index (line 124) | get index(): number | undefined {
method pattern (line 131) | get pattern(): PatternName {
method pattern (line 134) | set pattern(pattern) {
FILE: Tone/event/PatternGenerator.test.ts
function getArrayValues (line 6) | function getArrayValues(gen: Iterator<any>, length: number): any[] {
FILE: Tone/event/PatternGenerator.ts
type PatternName (line 7) | type PatternName =
FILE: Tone/event/Sequence.test.ts
method callback (line 314) | callback(time, value): void {
method callback (line 351) | callback(): void {
method callback (line 371) | callback(time, value): void {
method callback (line 387) | callback(time, value): void {
method callback (line 416) | callback(time): void {
method callback (line 440) | callback(time): void {
method callback (line 461) | callback(time): void {
FILE: Tone/event/Sequence.ts
type SequenceEventDescription (line 15) | type SequenceEventDescription<T> = Array<T | SequenceEventDescription<T>>;
type SequenceOptions (line 17) | interface SequenceOptions<T> extends Omit<ToneEventOptions<T>, "value"> {
class Sequence (line 40) | class Sequence<ValueType = any> extends ToneEvent<ValueType> {
method constructor (line 77) | constructor() {
method getDefaults (line 100) | static getDefaults(): SequenceOptions<any> {
method _seqCallback (line 116) | private _seqCallback(time: Seconds, value: any): void {
method events (line 125) | get events(): any[] {
method events (line 128) | set events(s) {
method start (line 140) | start(time?: TransportTime, offset?: number): this {
method stop (line 149) | stop(time?: TransportTime): this {
method subdivision (line 159) | get subdivision(): Seconds {
method _createSequence (line 166) | private _createSequence(array: any[]): any[] {
method _eventsUpdated (line 196) | private _eventsUpdated(): void {
method _rescheduleSequence (line 210) | private _rescheduleSequence(
method _indexTime (line 239) | private _indexTime(index: number): Seconds {
method clear (line 249) | clear(): this {
method dispose (line 254) | dispose(): this {
method loop (line 264) | get loop(): boolean | number {
method loop (line 267) | set loop(l) {
method loopStart (line 274) | get loopStart(): number {
method loopStart (line 277) | set loopStart(index) {
method loopEnd (line 285) | get loopEnd(): number {
method loopEnd (line 288) | set loopEnd(index) {
method startOffset (line 297) | get startOffset(): Ticks {
method startOffset (line 300) | set startOffset(start) {
method playbackRate (line 304) | get playbackRate(): Positive {
method playbackRate (line 307) | set playbackRate(rate) {
method probability (line 311) | get probability(): NormalRange {
method probability (line 314) | set probability(prob) {
method progress (line 318) | get progress(): NormalRange {
method humanize (line 322) | get humanize(): boolean | Time {
method humanize (line 325) | set humanize(variation) {
method length (line 332) | get length(): number {
FILE: Tone/event/ToneEvent.test.ts
method callback (line 232) | callback(): void {
method callback (line 247) | callback(time): void {
method callback (line 266) | callback(time): void {
method callback (line 285) | callback(): void {
method callback (line 300) | callback(): void {
method callback (line 315) | callback(): void {
method callback (line 330) | callback(): void {
method callback (line 348) | callback(time): void {
method callback (line 371) | callback(): void {
method callback (line 424) | callback(time): void {
method callback (line 442) | callback(time): void {
method callback (line 462) | callback(time): void {
FILE: Tone/event/ToneEvent.ts
type ToneEventCallback (line 25) | type ToneEventCallback<T> = (time: Seconds, value: T) => void;
type ToneEventOptions (line 27) | interface ToneEventOptions<T> extends ToneWithContextOptions {
class ToneEvent (line 57) | class ToneEvent<ValueType = any> extends ToneWithContext<
method constructor (line 127) | constructor() {
method getDefaults (line 150) | static getDefaults(): ToneEventOptions<any> {
method _rescheduleEvents (line 169) | private _rescheduleEvents(after: Ticks = -1): void {
method state (line 221) | get state(): BasicPlaybackState {
method startOffset (line 230) | get startOffset(): Ticks {
method startOffset (line 233) | set startOffset(offset) {
method probability (line 240) | get probability(): NormalRange {
method probability (line 243) | set probability(prob) {
method humanize (line 255) | get humanize(): Time | boolean {
method humanize (line 259) | set humanize(variation) {
method start (line 267) | start(time?: TransportTime | TransportTimeClass): this {
method stop (line 284) | stop(time?: TransportTime | TransportTimeClass): this {
method cancel (line 303) | cancel(time?: TransportTime | TransportTimeClass): this {
method _tick (line 318) | protected _tick(time: Seconds): void {
method _getLoopDuration (line 338) | protected _getLoopDuration(): Ticks {
method loop (line 352) | get loop(): boolean | number {
method loop (line 355) | set loop(loop) {
method playbackRate (line 368) | get playbackRate(): Positive {
method playbackRate (line 371) | set playbackRate(rate) {
method loopEnd (line 380) | get loopEnd(): Time {
method loopEnd (line 383) | set loopEnd(loopEnd) {
method loopStart (line 393) | get loopStart(): Time {
method loopStart (line 396) | set loopStart(loopStart) {
method progress (line 408) | get progress(): NormalRange {
method dispose (line 424) | dispose(): this {
FILE: Tone/fromContext.ts
type ClassesWithoutSingletons (line 15) | type ClassesWithoutSingletons = Omit<
type ToneObject (line 24) | type ToneObject = {
function bindTypeClass (line 37) | function bindTypeClass(context: Context, type) {
function fromContext (line 45) | function fromContext(context: Context): ToneObject {
FILE: Tone/index.ts
function now (line 23) | function now(): Seconds {
function immediate (line 32) | function immediate(): Seconds {
function getTransport (line 49) | function getTransport(): TransportInstance {
function getDestination (line 71) | function getDestination(): DestinationInstance {
function getListener (line 86) | function getListener(): ListenerInstance {
function getDraw (line 104) | function getDraw(): DrawInstance {
function loaded (line 120) | function loaded() {
FILE: Tone/instrument/AMSynth.ts
type AMSynthOptions (line 6) | type AMSynthOptions = ModulationSynthOptions;
class AMSynth (line 21) | class AMSynth extends ModulationSynth<AMSynthOptions> {
method constructor (line 30) | constructor() {
method dispose (line 45) | dispose(): this {
FILE: Tone/instrument/DuoSynth.ts
type DuoSynthOptions (line 22) | interface DuoSynthOptions extends MonophonicOptions {
class DuoSynth (line 38) | class DuoSynth extends Monophonic<DuoSynthOptions> {
method constructor (line 86) | constructor() {
method getLevelAtTime (line 156) | getLevelAtTime(time: Time): NormalRange {
method getDefaults (line 164) | static getDefaults(): DuoSynthOptions {
method _triggerEnvelopeAttack (line 214) | protected _triggerEnvelopeAttack(time: Seconds, velocity: number): void {
method _triggerEnvelopeRelease (line 224) | protected _triggerEnvelopeRelease(time: Seconds) {
method dispose (line 232) | dispose(): this {
FILE: Tone/instrument/FMSynth.ts
type FMSynthOptions (line 7) | interface FMSynthOptions extends ModulationSynthOptions {
class FMSynth (line 24) | class FMSynth extends ModulationSynth<FMSynthOptions> {
method constructor (line 35) | constructor() {
method getDefaults (line 54) | static getDefaults(): FMSynthOptions {
method dispose (line 60) | dispose(): this {
FILE: Tone/instrument/Instrument.ts
type InstrumentOptions (line 12) | interface InstrumentOptions extends ToneAudioNodeOptions {
method constructor (line 54) | constructor() {
method getDefaults (line 69) | static getDefaults(): InstrumentOptions {
method sync (line 89) | sync(): this {
method _syncState (line 104) | protected _syncState(): boolean {
method _syncMethod (line 118) | protected _syncMethod(method: string, timePosition: number): void {
method unsync (line 133) | unsync(): this {
method triggerAttackRelease (line 160) | triggerAttackRelease(
method dispose (line 203) | dispose(): this {
FILE: Tone/instrument/MembraneSynth.ts
type MembraneSynthOptions (line 9) | interface MembraneSynthOptions extends SynthOptions {
class MembraneSynth (line 27) | class MembraneSynth extends Synth<MembraneSynthOptions> {
method constructor (line 55) | constructor() {
method getDefaults (line 67) | static getDefaults(): MembraneSynthOptions {
method setNote (line 84) | setNote(note: Frequency | FrequencyClass, time?: Time): this {
method dispose (line 98) | dispose(): this {
FILE: Tone/instrument/MetalSynth.ts
type MetalSynthOptions (line 27) | interface MetalSynthOptions extends MonophonicOptions {
class MetalSynth (line 47) | class MetalSynth extends Monophonic<MetalSynthOptions> {
method constructor (line 99) | constructor() {
method getDefaults (line 172) | static getDefaults(): MetalSynthOptions {
method _triggerEnvelopeAttack (line 197) | protected _triggerEnvelopeAttack(
method _triggerEnvelopeRelease (line 219) | protected _triggerEnvelopeRelease(time: Seconds): this {
method getLevelAtTime (line 227) | getLevelAtTime(time: Time): NormalRange {
method modulationIndex (line 238) | get modulationIndex(): number {
method modulationIndex (line 241) | set modulationIndex(val) {
method harmonicity (line 251) | get harmonicity(): number {
method harmonicity (line 254) | set harmonicity(val) {
method resonance (line 264) | get resonance(): Frequency {
method resonance (line 267) | set resonance(val) {
method octaves (line 278) | get octaves(): number {
method octaves (line 281) | set octaves(val) {
method dispose (line 287) | dispose(): this {
FILE: Tone/instrument/ModulationSynth.ts
type ModulationSynthOptions (line 19) | interface ModulationSynthOptions extends SynthOptions {
method constructor (line 90) | constructor() {
method getDefaults (line 146) | static getDefaults(): ModulationSynthOptions {
method _triggerEnvelopeAttack (line 199) | protected _triggerEnvelopeAttack(time: Seconds, velocity: number): void {
method _triggerEnvelopeRelease (line 209) | protected _triggerEnvelopeRelease(time: Seconds) {
method getLevelAtTime (line 217) | getLevelAtTime(time: Time): NormalRange {
method dispose (line 222) | dispose(): this {
FILE: Tone/instrument/MonoSynth.ts
type MonoSynthOptions (line 21) | interface MonoSynthOptions extends MonophonicOptions {
class MonoSynth (line 45) | class MonoSynth extends Monophonic<MonoSynthOptions> {
method constructor (line 79) | constructor() {
method getDefaults (line 121) | static getDefaults(): MonoSynthOptions {
method _triggerEnvelopeAttack (line 178) | protected _triggerEnvelopeAttack(time: Seconds, velocity = 1): void {
method _triggerEnvelopeRelease (line 193) | protected _triggerEnvelopeRelease(time: Seconds): void {
method getLevelAtTime (line 199) | getLevelAtTime(time: Time): NormalRange {
method dispose (line 204) | dispose(): this {
FILE: Tone/instrument/Monophonic.ts
type onSilenceCallback (line 15) | type onSilenceCallback = (instrument: Monophonic<any>) => void;
type MonophonicOptions (line 17) | interface MonophonicOptions extends InstrumentOptions {
method constructor (line 51) | constructor() {
method getDefaults (line 62) | static getDefaults(): MonophonicOptions {
method triggerAttack (line 80) | triggerAttack(
method triggerRelease (line 101) | triggerRelease(time?: Time): this {
method setNote (line 140) | setNote(note: Frequency | FrequencyClass, time?: Time): this {
FILE: Tone/instrument/NoiseSynth.ts
type NoiseSynthOptions (line 14) | interface NoiseSynthOptions extends InstrumentOptions {
class NoiseSynth (line 31) | class NoiseSynth extends Instrument<NoiseSynthOptions> {
method constructor (line 45) | constructor() {
method getDefaults (line 74) | static getDefaults(): NoiseSynthOptions {
method triggerAttack (line 105) | triggerAttack(time?: Time, velocity: NormalRange = 1): this {
method triggerRelease (line 124) | triggerRelease(time?: Time): this {
method sync (line 131) | sync(): this {
method triggerAttackRelease (line 149) | triggerAttackRelease(
method dispose (line 161) | dispose(): this {
FILE: Tone/instrument/PluckSynth.ts
type PluckSynthOptions (line 9) | interface PluckSynthOptions extends InstrumentOptions {
class PluckSynth (line 26) | class PluckSynth extends Instrument<PluckSynthOptions> {
method constructor (line 54) | constructor() {
method getDefaults (line 81) | static getDefaults(): PluckSynthOptions {
method dampening (line 95) | get dampening(): Frequency {
method dampening (line 98) | set dampening(fq) {
method triggerAttack (line 102) | triggerAttack(note: Frequency, time?: Time): this {
method triggerRelease (line 117) | triggerRelease(time?: Time): this {
method dispose (line 122) | dispose(): this {
FILE: Tone/instrument/PolySynth.ts
type VoiceConstructor (line 26) | type VoiceConstructor<V> = {
type OmitMonophonicOptions (line 30) | type OmitMonophonicOptions<T> = Omit<T, "context" | "onsilence">;
type VoiceOptions (line 32) | type VoiceOptions<T> = T extends MembraneSynth
type PartialVoiceOptions (line 51) | type PartialVoiceOptions<T> = RecursivePartial<
type PolySynthOptions (line 55) | interface PolySynthOptions<Voice> extends InstrumentOptions {
class PolySynth (line 76) | class PolySynth<
method constructor (line 139) | constructor() {
method getDefaults (line 173) | static getDefaults(): PolySynthOptions<Synth> {
method activeVoices (line 184) | get activeVoices(): number {
method _makeVoiceAvailable (line 192) | private _makeVoiceAvailable(voice: Voice): void {
method _getNextAvailableVoice (line 206) | private _getNextAvailableVoice(): Voice | undefined {
method _collectGarbage (line 233) | private _collectGarbage(): void {
method _triggerAttack (line 255) | private _triggerAttack(
method _triggerRelease (line 278) | private _triggerRelease(notes: Frequency[], time: Seconds): void {
method _scheduleEvent (line 298) | private _scheduleEvent(
method triggerAttack (line 333) | triggerAttack(
method triggerRelease (line 358) | triggerRelease(notes: Frequency | Frequency[], time?: Time): this {
method triggerAttackRelease (line 378) | triggerAttackRelease(
method sync (line 409) | sync(): this {
method set (line 439) | set(options: RecursivePartial<VoiceOptions<Voice>>): this {
method get (line 452) | get(): VoiceOptions<Voice> {
method releaseAll (line 460) | releaseAll(time?: Time): this {
method dispose (line 468) | dispose(): this {
FILE: Tone/instrument/Sampler.test.ts
method onerror (line 113) | onerror(e) {
FILE: Tone/instrument/Sampler.ts
type SamplesMap (line 24) | interface SamplesMap {
type SamplerOptions (line 29) | interface SamplerOptions extends InstrumentOptions {
class Sampler (line 63) | class Sampler extends Instrument<SamplerOptions> {
method constructor (line 135) | constructor() {
method getDefaults (line 181) | static getDefaults(): SamplerOptions {
method _findClosest (line 199) | private _findClosest(midi: MidiNote): Interval {
method triggerAttack (line 220) | triggerAttack(
method triggerRelease (line 285) | triggerRelease(notes: Frequency | Frequency[], time?: Time): this {
method releaseAll (line 314) | releaseAll(time?: Time): this {
method sync (line 325) | sync(): this {
method triggerAttackRelease (line 340) | triggerAttackRelease(
method add (line 369) | add(
method loaded (line 392) | get loaded(): boolean {
method setLoopPoints (line 410) | setLoopPoints(loopStart: Time, loopEnd: Time): this {
method loopStart (line 419) | get loopStart(): Time {
method loopStart (line 422) | set loopStart(loopStart) {
method loopEnd (line 441) | get loopEnd(): Time {
method loopEnd (line 444) | set loopEnd(loopEnd) {
method loop (line 471) | get loop(): boolean {
method loop (line 474) | set loop(loop) {
method dispose (line 491) | dispose(): this {
FILE: Tone/instrument/Synth.ts
type SynthOptions (line 20) | interface SynthOptions extends MonophonicOptions {
class Synth (line 37) | class Synth<
method constructor (line 66) | constructor() {
method getDefaults (line 98) | static getDefaults(): SynthOptions {
method _triggerEnvelopeAttack (line 130) | protected _triggerEnvelopeAttack(time: Seconds, velocity: number): void {
method _triggerEnvelopeRelease (line 146) | protected _triggerEnvelopeRelease(time: Seconds): void {
method getLevelAtTime (line 151) | getLevelAtTime(time: Time): NormalRange {
method dispose (line 159) | dispose(): this {
FILE: Tone/signal/Abs.ts
class Abs (line 17) | class Abs extends SignalOperator<ToneAudioNodeOptions> {
method dispose (line 47) | dispose(): this {
FILE: Tone/signal/Add.ts
class Add (line 23) | class Add extends Signal {
method constructor (line 45) | constructor() {
method getDefaults (line 51) | static getDefaults(): SignalOptions<"number"> {
method dispose (line 57) | dispose(): this {
FILE: Tone/signal/AudioToGain.ts
class AudioToGain (line 10) | class AudioToGain extends SignalOperator<ToneAudioNodeOptions> {
method dispose (line 34) | dispose(): this {
FILE: Tone/signal/GainToAudio.ts
class GainToAudio (line 10) | class GainToAudio extends SignalOperator<ToneAudioNodeOptions> {
method dispose (line 34) | dispose(): this {
FILE: Tone/signal/GreaterThan.ts
type GreaterThanOptions (line 9) | type GreaterThanOptions = SignalOptions<"number">;
class GreaterThan (line 22) | class GreaterThan extends Signal<"number"> {
method constructor (line 57) | constructor() {
method getDefaults (line 80) | static getDefaults(): GreaterThanOptions {
method dispose (line 86) | dispose(): this {
FILE: Tone/signal/GreaterThanZero.ts
type GreaterThanZeroOptions (line 7) | type GreaterThanZeroOptions = SignalOperatorOptions;
class GreaterThanZero (line 19) | class GreaterThanZero extends SignalOperator<GreaterThanZeroOptions> {
method constructor (line 37) | constructor() {
method dispose (line 60) | dispose(): this {
FILE: Tone/signal/Multiply.ts
class Multiply (line 26) | class Multiply<
method constructor (line 61) | constructor() {
method getDefaults (line 83) | static getDefaults(): SignalOptions<any> {
method dispose (line 89) | dispose(): this {
FILE: Tone/signal/Negate.ts
class Negate (line 14) | class Negate extends SignalOperator<ToneAudioNodeOptions> {
method dispose (line 35) | dispose(): this {
FILE: Tone/signal/Pow.ts
type PowOptions (line 6) | interface PowOptions extends ToneAudioNodeOptions {
class Pow (line 19) | class Pow extends SignalOperator<PowOptions> {
method constructor (line 35) | constructor() {
method getDefaults (line 53) | static getDefaults(): PowOptions {
method _expFunc (line 63) | private _expFunc(exponent: number): WaveShaperMappingFn {
method value (line 72) | get value(): number {
method value (line 75) | set value(exponent: number) {
method dispose (line 83) | dispose(): this {
FILE: Tone/signal/Scale.ts
type ScaleOptions (line 11) | interface ScaleOptions extends ToneAudioNodeOptions {
class Scale (line 27) | class Scale<
method constructor (line 61) | constructor() {
method getDefaults (line 84) | static getDefaults(): ScaleOptions {
method min (line 94) | get min(): number {
method min (line 97) | set min(min) {
method max (line 105) | get max(): number {
method max (line 108) | set max(max) {
method _setRange (line 116) | private _setRange(): void {
method dispose (line 121) | dispose(): this {
FILE: Tone/signal/ScaleExp.ts
type ScaleExpOptions (line 6) | interface ScaleExpOptions extends ScaleOptions {
class ScaleExp (line 19) | class ScaleExp extends Scale<ScaleExpOptions> {
method constructor (line 34) | constructor() {
method getDefaults (line 49) | static getDefaults(): ScaleExpOptions {
method exponent (line 60) | get exponent(): Positive {
method exponent (line 63) | set exponent(exp) {
method dispose (line 67) | dispose(): this {
FILE: Tone/signal/Signal.ts
type SignalOptions (line 17) | interface SignalOptions<TypeName extends UnitName>
class Signal (line 45) | class Signal<TypeName extends UnitName = "number">
method constructor (line 70) | constructor() {
method getDefaults (line 89) | static getDefaults(): SignalOptions<any> {
method connect (line 97) | connect(destination: InputNode, outputNum = 0, inputNum = 0): this {
method disconnect (line 103) | disconnect(
method dispose (line 113) | dispose(): this {
method setValueAtTime (line 127) | setValueAtTime(value: UnitMap[TypeName], time: Time): this {
method getValueAtTime (line 132) | getValueAtTime(time: Time): UnitMap[TypeName] {
method setRampPoint (line 136) | setRampPoint(time: Time): this {
method linearRampToValueAtTime (line 141) | linearRampToValueAtTime(value: UnitMap[TypeName], time: Time): this {
method exponentialRampToValueAtTime (line 146) | exponentialRampToValueAtTime(value: UnitMap[TypeName], time: Time): th...
method exponentialRampTo (line 151) | exponentialRampTo(
method linearRampTo (line 160) | linearRampTo(
method targetRampTo (line 169) | targetRampTo(
method exponentialApproachValueAtTime (line 178) | exponentialApproachValueAtTime(
method setTargetAtTime (line 187) | setTargetAtTime(
method setValueCurveAtTime (line 196) | setValueCurveAtTime(
method cancelScheduledValues (line 206) | cancelScheduledValues(time: Time): this {
method cancelAndHoldAtTime (line 211) | cancelAndHoldAtTime(time: Time): this {
method rampTo (line 216) | rampTo(value: UnitMap[TypeName], rampTime: Time, startTime?: Time): th...
method value (line 221) | get value(): UnitMap[TypeName] {
method value (line 224) | set value(value: UnitMap[TypeName]) {
method convert (line 228) | get convert(): boolean {
method convert (line 231) | set convert(convert: boolean) {
method units (line 235) | get units(): UnitName {
method overridden (line 239) | get overridden(): boolean {
method overridden (line 242) | set overridden(overridden: boolean) {
method maxValue (line 246) | get maxValue(): number {
method minValue (line 249) | get minValue(): number {
method apply (line 256) | apply(param: Param | AudioParam): this {
function connectSignal (line 288) | function connectSignal(
function disconnectSignal (line 330) | function disconnectSignal(
FILE: Tone/signal/SignalOperator.test.ts
class TestSignalOperator (line 7) | class TestSignalOperator extends SignalOperator<SignalOperatorOptions> {
method constructor (line 13) | constructor(options: SignalOperatorOptions) {
FILE: Tone/signal/SignalOperator.ts
type SignalOperatorOptions (line 9) | type SignalOperatorOptions = ToneAudioNodeOptions;
method constructor (line 18) | constructor() {
method connect (line 27) | connect(destination: InputNode, outputNum = 0, inputNum = 0): this {
method disconnect (line 33) | disconnect(destination: InputNode, outputNum = 0, inputNum = 0): this {
FILE: Tone/signal/Subtract.ts
class Subtract (line 27) | class Subtract extends Signal {
method constructor (line 55) | constructor() {
method getDefaults (line 63) | static getDefaults(): SignalOptions<"number"> {
method dispose (line 69) | dispose(): this {
FILE: Tone/signal/SyncedSignal.ts
class SyncedSignal (line 21) | class SyncedSignal<
method constructor (line 54) | constructor() {
method _onTick (line 88) | private _onTick(time: Seconds): void {
method _anchorValue (line 100) | private _anchorValue(time: Seconds): void {
method getValueAtTime (line 107) | getValueAtTime(time: TransportTime): UnitMap[TypeName] {
method setValueAtTime (line 115) | setValueAtTime(value: UnitMap[TypeName], time: TransportTime) {
method linearRampToValueAtTime (line 124) | linearRampToValueAtTime(value: UnitMap[TypeName], time: TransportTime) {
method exponentialRampToValueAtTime (line 133) | exponentialRampToValueAtTime(
method setTargetAtTime (line 145) | setTargetAtTime(
method cancelScheduledValues (line 158) | cancelScheduledValues(startTime: TransportTime): this {
method setValueCurveAtTime (line 167) | setValueCurveAtTime(
method cancelAndHoldAtTime (line 182) | cancelAndHoldAtTime(time: TransportTime): this {
method setRampPoint (line 191) | setRampPoint(time: TransportTime): this {
method exponentialRampTo (line 200) | exponentialRampTo(
method linearRampTo (line 213) | linearRampTo(
method targetRampTo (line 226) | targetRampTo(
method dispose (line 239) | dispose(): this {
FILE: Tone/signal/ToneConstantSource.ts
type ToneConstantSourceOptions (line 10) | interface ToneConstantSourceOptions<TypeName extends UnitName>
class ToneConstantSource (line 24) | class ToneConstantSource<
method constructor (line 44) | constructor() {
method getDefaults (line 69) | static getDefaults(): ToneConstantSourceOptions<any> {
method _contextStarted (line 80) | private _contextStarted() {
method start (line 93) | start(time?: Time): this {
method _stopSource (line 101) | protected _stopSource(time?: Seconds): void {
method dispose (line 108) | dispose(): this {
FILE: Tone/signal/WaveShaper.ts
type WaveShaperMappingFn (line 8) | type WaveShaperMappingFn = (value: number, index?: number) => number;
type WaveShaperMapping (line 10) | type WaveShaperMapping = WaveShaperMappingFn | number[] | Float32Array;
type WaveShaperOptions (line 12) | interface WaveShaperOptions extends ToneAudioNodeOptions {
class WaveShaper (line 29) | class WaveShaper extends SignalOperator<WaveShaperOptions> {
method constructor (line 61) | constructor() {
method getDefaults (line 74) | static getDefaults(): WaveShaperOptions {
method initCurve (line 84) | private initCurve(mapping?: WaveShaperMapping, length?: number): void {
method setMap (line 104) | setMap(mapping: WaveShaperMappingFn, length = 1024): this {
method curve (line 119) | get curve(): Float32Array | null {
method curve (line 123) | set curve(mapping: Float32Array | null) {
method oversample (line 131) | get oversample(): OverSampleType {
method oversample (line 135) | set oversample(oversampling: OverSampleType) {
method dispose (line 149) | dispose(): this {
FILE: Tone/signal/Zero.ts
class Zero (line 15) | class Zero extends SignalOperator<ToneAudioNodeOptions> {
method constructor (line 34) | constructor() {
method dispose (line 45) | dispose(): this {
FILE: Tone/source/Noise.ts
type NoiseType (line 8) | type NoiseType = "white" | "brown" | "pink";
type NoiseOptions (line 10) | interface NoiseOptions extends SourceOptions {
class Noise (line 37) | class Noise extends Source<NoiseOptions> {
method constructor (line 71) | constructor() {
method getDefaults (line 83) | static getDefaults(): NoiseOptions {
method type (line 98) | get type(): NoiseType {
method type (line 101) | set type(type: NoiseType) {
method playbackRate (line 118) | get playbackRate(): Positive {
method playbackRate (line 121) | set playbackRate(rate: Positive) {
method _start (line 131) | protected _start(time?: Time): void {
method _stop (line 151) | protected _stop(time?: Time): void {
method fadeIn (line 161) | get fadeIn(): Time {
method fadeIn (line 164) | set fadeIn(time) {
method fadeOut (line 174) | get fadeOut(): Time {
method fadeOut (line 177) | set fadeOut(time) {
method _restart (line 184) | protected _restart(time?: Time): void {
method dispose (line 193) | dispose(): this {
constant BUFFER_LENGTH (line 207) | const BUFFER_LENGTH = 44100 * 5;
constant NUM_CHANNELS (line 208) | const NUM_CHANNELS = 2;
type NoiseCache (line 213) | interface NoiseCache {
method brown (line 232) | get brown(): ToneAudioBuffer {
method pink (line 251) | get pink(): ToneAudioBuffer {
method white (line 278) | get white(): ToneAudioBuffer {
FILE: Tone/source/OneShotSource.ts
type OneShotSourceCurve (line 11) | type OneShotSourceCurve = "linear" | "exponential";
type onEndedCallback (line 13) | type onEndedCallback = (source: OneShotSource<any>) => void;
type OneShotSourceOptions (line 15) | interface OneShotSourceOptions extends ToneAudioNodeOptions {
method constructor (line 82) | constructor(options: OneShotSourceOptions) {
method getDefaults (line 91) | static getDefaults(): OneShotSourceOptions {
method _startGain (line 114) | protected _startGain(time: Seconds, gain: GainFactor = 1): this {
method stop (line 151) | stop(time?: Time): this {
method _stopGain (line 161) | protected _stopGain(time: Seconds): this {
method _onended (line 198) | protected _onended(): void {
method state (line 236) | get state(): BasicPlaybackState {
method cancelStop (line 243) | cancelStop(): this {
method dispose (line 255) | dispose(): this {
FILE: Tone/source/Source.ts
type onStopCallback (line 23) | type onStopCallback = (source: Source<any>) => void;
type SourceOptions (line 25) | interface SourceOptions extends ToneAudioNodeOptions {
method constructor (line 108) | constructor(options: SourceOptions) {
method getDefaults (line 123) | static getDefaults(): SourceOptions {
method state (line 139) | get state(): BasicPlaybackState {
method mute (line 160) | get mute(): boolean {
method mute (line 163) | set mute(mute: boolean) {
method _clampToCurrentTime (line 180) | private _clampToCurrentTime(time: Seconds): Seconds {
method start (line 196) | start(time?: Time, offset?: Time, duration?: Time): this {
method stop (line 264) | stop(time?: Time): this {
method restart (line 293) | restart(time?: Time, offset?: Time, duration?: Time): this {
method sync (line 317) | sync(): this {
method unsync (line 368) | unsync(): this {
method dispose (line 389) | dispose(): this {
FILE: Tone/source/UserMedia.ts
type UserMediaOptions (line 15) | interface UserMediaOptions extends ToneAudioNodeOptions {
class UserMedia (line 39) | class UserMedia extends ToneAudioNode<UserMediaOptions> {
method constructor (line 75) | constructor() {
method getDefaults (line 92) | static getDefaults(): UserMediaOptions {
method open (line 107) | async open(
method close (line 169) | close(): this {
method enumerateDevices (line 192) | static async enumerateDevices(): Promise<MediaDeviceInfo[]> {
method state (line 203) | get state() {
method deviceId (line 215) | get deviceId(): string | undefined {
method groupId (line 228) | get groupId(): string | undefined {
method label (line 241) | get label(): string | undefined {
method mute (line 259) | get mute(): boolean {
method mute (line 262) | set mute(mute) {
method dispose (line 266) | dispose(): this {
method supported (line 277) | static get supported(): boolean {
FILE: Tone/source/buffer/GrainPlayer.test.ts
method onerror (line 96) | onerror() {
FILE: Tone/source/buffer/GrainPlayer.ts
type GrainPlayerOptions (line 11) | interface GrainPlayerOptions extends SourceOptions {
class GrainPlayer (line 32) | class GrainPlayer extends Source<GrainPlayerOptions> {
method constructor (line 94) | constructor() {
method getDefaults (line 129) | static getDefaults(): GrainPlayerOptions {
method _start (line 147) | protected _start(time?: Time, offset?: Time, duration?: Time): void {
method restart (line 167) | restart(time?: Seconds, offset?: Time, duration?: Time): this {
method _restart (line 172) | protected _restart(time?: Seconds, offset?: Time, duration?: Time): vo...
method _stop (line 180) | protected _stop(time?: Time): void {
method _onstop (line 187) | private _onstop(time: Seconds): void {
method _tick (line 199) | private _tick(time: Seconds): void {
method playbackRate (line 243) | get playbackRate(): Positive {
method playbackRate (line 246) | set playbackRate(rate) {
method loopStart (line 255) | get loopStart(): Time {
method loopStart (line 258) | set loopStart(time) {
method loopEnd (line 268) | get loopEnd(): Time {
method loopEnd (line 271) | set loopEnd(time) {
method reverse (line 281) | get reverse() {
method reverse (line 285) | set reverse(rev) {
method grainSize (line 293) | get grainSize(): Time {
method grainSize (line 296) | set grainSize(size) {
method overlap (line 307) | get overlap(): Time {
method overlap (line 310) | set overlap(time) {
method loaded (line 319) | get loaded(): boolean {
method dispose (line 323) | dispose(): this {
FILE: Tone/source/buffer/Player.test.ts
method onerror (line 132) | onerror(e) {
method onload (line 143) | onload(): void {
method onload (line 701) | onload(): void {
FILE: Tone/source/buffer/Player.ts
type PlayerOptions (line 14) | interface PlayerOptions extends SourceOptions {
class Player (line 36) | class Player extends Source<PlayerOptions> {
method constructor (line 123) | constructor() {
method getDefaults (line 145) | static getDefaults(): PlayerOptions {
method load (line 169) | async load(url: string): Promise<this> {
method _getProgressAtTime (line 179) | private _getProgressAtTime(time: Seconds): Seconds {
method progress (line 216) | get progress(): Seconds {
method _onload (line 224) | private _onload(callback: () => void = noOp): void {
method _onSourceEnd (line 234) | private _onSourceEnd(source: ToneBufferSource): void {
method start (line 260) | start(time?: Time, offset?: Time, duration?: Time): this {
method _start (line 268) | protected _start(startTime?: Time, offset?: Time, duration?: Time): vo...
method _stop (line 348) | protected _stop(time?: Time): void {
method restart (line 361) | restart(time?: Seconds, offset?: Time, duration?: Time): this {
method _restart (line 366) | protected _restart(time?: Seconds, offset?: Time, duration?: Time): vo...
method seek (line 383) | seek(offset: Time, when?: Time): this {
method setLoopPoints (line 408) | setLoopPoints(loopStart: Time, loopEnd: Time): this {
method loopStart (line 417) | get loopStart(): Time {
method loopStart (line 420) | set loopStart(loopStart) {
method loopEnd (line 434) | get loopEnd(): Time {
method loopEnd (line 437) | set loopEnd(loopEnd) {
method buffer (line 451) | get buffer(): ToneAudioBuffer {
method buffer (line 454) | set buffer(buffer) {
method loop (line 465) | get loop(): boolean {
method loop (line 468) | set loop(loop) {
method playbackRate (line 496) | get playbackRate(): Positive {
method playbackRate (line 499) | set playbackRate(rate) {
method reverse (line 533) | get reverse(): boolean {
method reverse (line 536) | set reverse(rev) {
method loaded (line 543) | get loaded(): boolean {
method dispose (line 547) | dispose(): this {
FILE: Tone/source/buffer/Players.test.ts
method onerror (line 77) | onerror() {
FILE: Tone/source/buffer/Players.ts
type PlayersOptions (line 17) | interface PlayersOptions extends SourceOptions {
class Players (line 32) | class Players extends ToneAudioNode<PlayersOptions> {
method constructor (line 89) | constructor() {
method getDefaults (line 120) | static getDefaults(): PlayersOptions {
method mute (line 136) | get mute(): boolean {
method mute (line 139) | set mute(mute) {
method fadeIn (line 146) | get fadeIn(): Time {
method fadeIn (line 149) | set fadeIn(fadeIn) {
method fadeOut (line 159) | get fadeOut(): Time {
method fadeOut (line 162) | set fadeOut(fadeOut) {
method state (line 172) | get state(): BasicPlaybackState {
method has (line 183) | has(name: string): boolean {
method player (line 191) | player(name: string): Player {
method loaded (line 211) | get loaded(): boolean {
method add (line 227) | add(
method stopAll (line 244) | stopAll(time?: Time): this {
method dispose (line 249) | dispose(): this {
FILE: Tone/source/buffer/ToneBufferSource.test.ts
method onerror (line 88) | onerror() {
FILE: Tone/source/buffer/ToneBufferSource.ts
type ToneBufferSourceCurve (line 16) | type ToneBufferSourceCurve = OneShotSourceCurve;
type ToneBufferSourceOptions (line 18) | interface ToneBufferSourceOptions extends OneShotSourceOptions {
class ToneBufferSource (line 35) | class ToneBufferSource extends OneShotSource<ToneBufferSourceOptions> {
method constructor (line 69) | constructor() {
method getDefaults (line 103) | static getDefaults(): ToneBufferSourceOptions {
method fadeIn (line 118) | get fadeIn(): Time {
method fadeIn (line 121) | set fadeIn(t: Time) {
method fadeOut (line 128) | get fadeOut(): Time {
method fadeOut (line 131) | set fadeOut(t: Time) {
method curve (line 138) | get curve(): ToneBufferSourceCurve {
method curve (line 141) | set curve(t) {
method start (line 152) | start(
method _stopSource (line 212) | protected _stopSource(time?: Seconds): void {
method loopStart (line 223) | get loopStart(): Time {
method loopStart (line 226) | set loopStart(loopStart: Time) {
method loopEnd (line 233) | get loopEnd(): Time {
method loopEnd (line 236) | set loopEnd(loopEnd: Time) {
method buffer (line 243) | get buffer(): ToneAudioBuffer {
method buffer (line 246) | set buffer(buffer: ToneAudioBuffer) {
method loop (line 253) | get loop(): boolean {
method loop (line 256) | set loop(loop: boolean) {
method dispose (line 266) | dispose(): this {
FILE: Tone/source/oscillator/AMOscillator.ts
class AMOscillator (line 40) | class AMOscillator
method constructor (line 99) | constructor() {
method getDefaults (line 138) | static getDefaults(): AMOscillatorOptions {
method _start (line 148) | protected _start(time: Seconds): void {
method _stop (line 156) | protected _stop(time: Seconds): void {
method _restart (line 161) | protected _restart(time: Seconds): void {
method type (line 169) | get type(): ToneOscillatorType {
method type (line 172) | set type(type: ToneOscillatorType) {
method baseType (line 176) | get baseType(): OscillatorType {
method baseType (line 179) | set baseType(baseType: OscillatorType) {
method partialCount (line 183) | get partialCount(): number {
method partialCount (line 186) | set partialCount(partialCount: number) {
method modulationType (line 193) | get modulationType(): ToneOscillatorType {
method modulationType (line 196) | set modulationType(type: ToneOscillatorType) {
method phase (line 200) | get phase(): Degrees {
method phase (line 203) | set phase(phase: Degrees) {
method partials (line 208) | get partials(): number[] {
method partials (line 211) | set partials(partials: number[]) {
method asArray (line 215) | async asArray(length = 1024): Promise<Float32Array> {
method dispose (line 222) | dispose(): this {
FILE: Tone/source/oscillator/FMOscillator.ts
class FMOscillator (line 45) | class FMOscillator
method constructor (line 101) | constructor() {
method getDefaults (line 161) | static getDefaults(): FMOscillatorOptions {
method _start (line 172) | protected _start(time: Time): void {
method _stop (line 180) | protected _stop(time: Time): void {
method _restart (line 185) | protected _restart(time: Seconds): this {
method type (line 191) | get type(): ToneOscillatorType {
method type (line 194) | set type(type: ToneOscillatorType) {
method baseType (line 198) | get baseType(): OscillatorType {
method baseType (line 201) | set baseType(baseType: OscillatorType) {
method partialCount (line 205) | get partialCount(): number {
method partialCount (line 208) | set partialCount(partialCount: number) {
method modulationType (line 215) | get modulationType(): ToneOscillatorType {
method modulationType (line 218) | set modulationType(type: ToneOscillatorType) {
method phase (line 222) | get phase(): Degrees {
method phase (line 225) | set phase(phase: Degrees) {
method partials (line 230) | get partials(): number[] {
method partials (line 233) | set partials(partials: number[]) {
method asArray (line 237) | async asArray(length = 1024): Promise<Float32Array> {
method dispose (line 244) | dispose(): this {
FILE: Tone/source/oscillator/FatOscillator.ts
class FatOscillator (line 31) | class FatOscillator
method constructor (line 81) | constructor() {
method getDefaults (line 112) | static getDefaults(): FatOscillatorOptions {
method _start (line 123) | protected _start(time: Time): void {
method _stop (line 131) | protected _stop(time: Time): void {
method _restart (line 136) | protected _restart(time: Seconds): void {
method _forEach (line 143) | private _forEach(iterator: (osc: Oscillator, index: number) => void): ...
method type (line 152) | get type(): ToneOscillatorType {
method type (line 155) | set type(type: ToneOscillatorType) {
method spread (line 169) | get spread(): Cents {
method spread (line 172) | set spread(spread: Cents) {
method count (line 188) | get count(): number {
method count (line 191) | set count(count: number) {
method phase (line 223) | get phase(): Degrees {
method phase (line 226) | set phase(phase: Degrees) {
method baseType (line 233) | get baseType(): OscillatorType {
method baseType (line 236) | set baseType(baseType: OscillatorType) {
method partials (line 241) | get partials(): number[] {
method partials (line 244) | set partials(partials: number[]) {
method partialCount (line 253) | get partialCount(): number {
method partialCount (line 256) | set partialCount(partialCount: number) {
method asArray (line 262) | async asArray(length = 1024): Promise<Float32Array> {
method dispose (line 269) | dispose(): this {
FILE: Tone/source/oscillator/LFO.ts
type LFOOptions (line 32) | type LFOOptions = {
class LFO (line 50) | class LFO extends ToneAudioNode<LFOOptions> {
method constructor (line 130) | constructor() {
method getDefaults (line 175) | static getDefaults(): LFOOptions {
method start (line 190) | start(time?: Time): this {
method stop (line 201) | stop(time?: Time): this {
method sync (line 216) | sync(): this {
method unsync (line 225) | unsync(): this {
method _setStoppedValue (line 234) | private _setStoppedValue() {
method min (line 242) | get min(): number {
method min (line 245) | set min(min) {
method max (line 253) | get max(): number {
method max (line 256) | set max(max) {
method type (line 265) | get type(): ToneOscillatorType {
method type (line 268) | set type(type) {
method partials (line 277) | get partials(): number[] {
method partials (line 280) | set partials(partials) {
method phase (line 288) | get phase(): Degrees {
method phase (line 291) | set phase(phase) {
method units (line 299) | get units(): UnitName {
method units (line 302) | set units(val) {
method state (line 314) | get state(): BasicPlaybackState {
method connect (line 323) | connect(node: InputNode, outputNum?: number, inputNum?: number): this {
method disconnect (line 335) | disconnect(destination?: InputNode, outputNum = 0, inputNum = 0): this {
method dispose (line 352) | dispose(): this {
FILE: Tone/source/oscillator/OmniOscillator.ts
type AnyOscillator (line 32) | type AnyOscillator =
type OmniOscillatorSource (line 43) | interface OmniOscillatorSource {
type OmniOscSourceType (line 55) | type OmniOscSourceType = keyof OmniOscillatorSource;
type IsAmOrFmOscillator (line 58) | type IsAmOrFmOscillator<Osc, Ret> = Osc extends AMOscillator
type IsFatOscillator (line 63) | type IsFatOscillator<Osc, Ret> = Osc extends FatOscillator ? Ret : undef...
type IsPWMOscillator (line 64) | type IsPWMOscillator<Osc, Ret> = Osc extends PWMOscillator ? Ret : undef...
type IsPulseOscillator (line 65) | type IsPulseOscillator<Osc, Ret> = Osc extends PulseOscillator
type IsFMOscillator (line 68) | type IsFMOscillator<Osc, Ret> = Osc extends FMOscillator ? Ret : undefined;
type AnyOscillatorConstructor (line 70) | type AnyOscillatorConstructor = new (...args: any[]) => AnyOscillator;
class OmniOscillator (line 91) | class OmniOscillator<OscType extends AnyOscillator>
method constructor (line 116) | constructor() {
method getDefaults (line 140) | static getDefaults(): OmniOscillatorOptions {
method _start (line 154) | protected _start(time: Time): void {
method _stop (line 161) | protected _stop(time: Time): void {
method _restart (line 165) | protected _restart(time: Seconds): this {
method type (line 183) | get type(): OmniOscillatorType {
method type (line 190) | set type(type) {
method partials (line 220) | get partials(): number[] {
method partials (line 223) | set partials(partials) {
method partialCount (line 232) | get partialCount(): number {
method partialCount (line 235) | set partialCount(partialCount) {
method set (line 244) | set(props: Partial<OmniOscillatorOptions>): this {
method _createNewOscillator (line 257) | private _createNewOscillator(oscType: OmniOscSourceType): void {
method phase (line 282) | get phase(): Degrees {
method phase (line 285) | set phase(phase) {
method sourceType (line 295) | get sourceType(): OmniOscSourceType {
method sourceType (line 298) | set sourceType(sType) {
method _getOscType (line 323) | private _getOscType<SourceType extends OmniOscSourceType>(
method baseType (line 337) | get baseType(): OscillatorType | "pwm" | "pulse" {
method baseType (line 340) | set baseType(baseType) {
method width (line 355) | get width(): IsPulseOscillator<OscType, Signal<"audioRange">> {
method count (line 373) | get count(): IsFatOscillator<OscType, number> {
method count (line 380) | set count(count) {
method spread (line 390) | get spread(): IsFatOscillator<OscType, Cents> {
method spread (line 397) | set spread(spread) {
method modulationType (line 407) | get modulationType(): IsAmOrFmOscillator<OscType, ToneOscillatorType> {
method modulationType (line 420) | set modulationType(mType) {
method modulationIndex (line 434) | get modulationIndex(): IsFMOscillator<OscType, Signal<"positive">> {
method harmonicity (line 449) | get harmonicity(): IsAmOrFmOscillator<OscType, Signal<"positive">> {
method modulationFrequency (line 469) | get modulationFrequency(): IsPWMOscillator<OscType, Signal<"frequency"...
method asArray (line 480) | async asArray(length = 1024): Promise<Float32Array> {
method dispose (line 484) | dispose(): this {
FILE: Tone/source/oscillator/Oscillator.ts
class Oscillator (line 37) | class Oscillator
method constructor (line 89) | constructor() {
method getDefaults (line 122) | static getDefaults(): ToneOscillatorOptions {
method _start (line 136) | protected _start(time?: Time): void {
method _cleanUpConnections (line 165) | private _cleanUpConnections(oscillator: ToneOscillatorNode): void {
method _stop (line 178) | protected _stop(time?: Time): void {
method _restart (line 189) | protected _restart(time?: Time): this {
method syncFrequency (line 211) | syncFrequency(): this {
method unsyncFrequency (line 220) | unsyncFrequency(): this {
method _getCachedPeriodicWave (line 243) | private _getCachedPeriodicWave():
method type (line 277) | get type(): ToneOscillatorType {
method type (line 280) | set type(type) {
method baseType (line 329) | get baseType(): OscillatorType {
method baseType (line 335) | set baseType(baseType) {
method partialCount (line 347) | get partialCount(): number {
method partialCount (line 350) | set partialCount(p) {
method _getRealImaginary (line 380) | private _getRealImaginary(
method _inverseFFT (line 460) | private _inverseFFT(
method getInitialValue (line 478) | getInitialValue(): AudioRange {
method partials (line 497) | get partials(): number[] {
method partials (line 500) | set partials(partials) {
method phase (line 508) | get phase(): Degrees {
method phase (line 511) | set phase(phase) {
method asArray (line 517) | async asArray(length = 1024): Promise<Float32Array> {
method dispose (line 521) | dispose(): this {
FILE: Tone/source/oscillator/OscillatorInterface.ts
type ToneOscillatorInterface (line 16) | interface ToneOscillatorInterface {
function generateWaveform (line 115) | async function generateWaveform(
type PartialsRange (line 142) | type PartialsRange =
type SineWithPartials (line 179) | type SineWithPartials = `sine${PartialsRange}`;
type SquareWithPartials (line 181) | type SquareWithPartials = `square${PartialsRange}`;
type SawtoothWithPartials (line 183) | type SawtoothWithPartials = `sawtooth${PartialsRange}`;
type TriangleWithPartials (line 185) | type TriangleWithPartials = `triangle${PartialsRange}`;
type TypeWithPartials (line 187) | type TypeWithPartials =
type BaseOscillatorOptions (line 193) | interface BaseOscillatorOptions extends SourceOptions {
type NonCustomOscillatorType (line 199) | type NonCustomOscillatorType = Exclude<OscillatorType, "custom">;
type AllNonCustomOscillatorType (line 201) | type AllNonCustomOscillatorType = NonCustomOscillatorType | TypeWithPart...
type ToneOscillatorType (line 203) | type ToneOscillatorType = AllNonCustomOscillatorType | "custom";
type ExtendedToneOscillatorType (line 205) | type ExtendedToneOscillatorType = ToneOscillatorType | "pwm" | "pulse";
type ToneCustomOscillatorOptions (line 210) | interface ToneCustomOscillatorOptions extends BaseOscillatorOptions {
type ToneTypeOscillatorOptions (line 215) | interface ToneTypeOscillatorOptions extends BaseOscillatorOptions {
type TonePartialOscillatorOptions (line 220) | interface TonePartialOscillatorOptions extends BaseOscillatorOptions {
type ToneOscillatorConstructorOptions (line 224) | type ToneOscillatorConstructorOptions =
type ToneOscillatorOptions (line 229) | interface ToneOscillatorOptions extends BaseOscillatorOptions {
type FMBaseOscillatorOptions (line 238) | interface FMBaseOscillatorOptions extends BaseOscillatorOptions {
type FMCustomOscillatorOptions (line 244) | interface FMCustomOscillatorOptions extends FMBaseOscillatorOptions {
type FMTypeOscillatorOptions (line 249) | interface FMTypeOscillatorOptions extends FMBaseOscillatorOptions {
type FMPartialsOscillatorOptions (line 254) | interface FMPartialsOscillatorOptions extends FMBaseOscillatorOptions {
type FMConstructorOptions (line 258) | type FMConstructorOptions =
type FMOscillatorOptions (line 263) | interface FMOscillatorOptions extends ToneOscillatorOptions {
type AMBaseOscillatorOptions (line 272) | interface AMBaseOscillatorOptions extends BaseOscillatorOptions {
type AMCustomOscillatorOptions (line 277) | interface AMCustomOscillatorOptions extends AMBaseOscillatorOptions {
type AMTypeOscillatorOptions (line 282) | interface AMTypeOscillatorOptions extends AMBaseOscillatorOptions {
type AMPartialsOscillatorOptions (line 287) | interface AMPartialsOscillatorOptions extends AMBaseOscillatorOptions {
type AMConstructorOptions (line 291) | type AMConstructorOptions =
type AMOscillatorOptions (line 296) | interface AMOscillatorOptions extends ToneOscillatorOptions {
type FatBaseOscillatorOptions (line 303) | interface FatBaseOscillatorOptions extends BaseOscillatorOptions {
type FatCustomOscillatorOptions (line 308) | interface FatCustomOscillatorOptions extends FatBaseOscillatorOptions {
type FatTypeOscillatorOptions (line 313) | interface FatTypeOscillatorOptions extends FatBaseOscillatorOptions {
type FatPartialsOscillatorOptions (line 318) | interface FatPartialsOscillatorOptions extends FatBaseOscillatorOptions {
type FatConstructorOptions (line 322) | type FatConstructorOptions =
type FatOscillatorOptions (line 327) | interface FatOscillatorOptions extends ToneOscillatorOptions {
type PulseOscillatorOptions (line 335) | interface PulseOscillatorOptions extends BaseOscillatorOptions {
type PWMOscillatorOptions (line 343) | interface PWMOscillatorOptions extends BaseOscillatorOptions {
type FMSineWithPartials (line 355) | type FMSineWithPartials = `fmsine${PartialsRange}`;
type FMSquareWithPartials (line 357) | type FMSquareWithPartials = `fmsquare${PartialsRange}`;
type FMSawtoothWithPartials (line 359) | type FMSawtoothWithPartials = `fmsawtooth${PartialsRange}`;
type FMTriangleWithPartials (line 361) | type FMTriangleWithPartials = `fmtriangle${PartialsRange}`;
type FMTypeWithPartials (line 363) | type FMTypeWithPartials =
type AMSineWithPartials (line 372) | type AMSineWithPartials = `amsine${PartialsRange}`;
type AMSquareWithPartials (line 374) | type AMSquareWithPartials = `amsquare${PartialsRange}`;
type AMSawtoothWithPartials (line 376) | type AMSawtoothWithPartials = `amsawtooth${PartialsRange}`;
type AMTriangleWithPartials (line 378) | type AMTriangleWithPartials = `amtriangle${PartialsRange}`;
type AMTypeWithPartials (line 380) | type AMTypeWithPartials =
type FatSineWithPartials (line 389) | type FatSineWithPartials = `fatsine${PartialsRange}`;
type FatSquareWithPartials (line 391) | type FatSquareWithPartials = `fatsquare${PartialsRange}`;
type FatSawtoothWithPartials (line 393) | type FatSawtoothWithPartials = `fatsawtooth${PartialsRange}`;
type FatTriangleWithPartials (line 395) | type FatTriangleWithPartials = `fattriangle${PartialsRange}`;
type FatTypeWithPartials (line 397) | type FatTypeWithPartials =
type OmniFMCustomOscillatorOptions (line 406) | interface OmniFMCustomOscillatorOptions extends FMBaseOscillatorOptions {
type OmniFMTypeOscillatorOptions (line 411) | interface OmniFMTypeOscillatorOptions extends FMBaseOscillatorOptions {
type OmniFMPartialsOscillatorOptions (line 416) | interface OmniFMPartialsOscillatorOptions extends FMBaseOscillatorOptions {
type OmniAMCustomOscillatorOptions (line 423) | interface OmniAMCustomOscillatorOptions extends AMBaseOscillatorOptions {
type OmniAMTypeOscillatorOptions (line 428) | interface OmniAMTypeOscillatorOptions extends AMBaseOscillatorOptions {
type OmniAMPartialsOscillatorOptions (line 433) | interface OmniAMPartialsOscillatorOptions extends AMBaseOscillatorOptions {
type OmniFatCustomOscillatorOptions (line 440) | interface OmniFatCustomOscillatorOptions extends FatBaseOscillatorOptions {
type OmniFatTypeOscillatorOptions (line 445) | interface OmniFatTypeOscillatorOptions extends FatBaseOscillatorOptions {
type OmniFatPartialsOscillatorOptions (line 450) | interface OmniFatPartialsOscillatorOptions extends FatBaseOscillatorOpti...
type OmniOscillatorType (line 454) | type OmniOscillatorType =
type OmniOscillatorOptions (line 478) | type OmniOscillatorOptions =
type OmitSourceOptions (line 492) | type OmitSourceOptions<T extends BaseOscillatorOptions> = Omit<
type OmniOscillatorSynthOptions (line 500) | type OmniOscillatorSynthOptions =
FILE: Tone/source/oscillator/PWMOscillator.ts
class PWMOscillator (line 28) | class PWMOscillator
method constructor (line 79) | constructor() {
method getDefaults (line 113) | static getDefaults(): PWMOscillatorOptions {
method _start (line 125) | protected _start(time: Time): void {
method _stop (line 134) | protected _stop(time: Time): void {
method _restart (line 143) | protected _restart(time: Seconds): void {
method type (line 151) | get type(): "pwm" {
method baseType (line 158) | get baseType(): "pwm" {
method partials (line 165) | get partials(): number[] {
method partialCount (line 172) | get partialCount(): number {
method phase (line 179) | get phase(): Degrees {
method phase (line 182) | set phase(phase: Degrees) {
method asArray (line 186) | async asArray(length = 1024): Promise<Float32Array> {
method dispose (line 193) | dispose(): this {
FILE: Tone/source/oscillator/PulseOscillator.ts
class PulseOscillator (line 58) | class PulseOscillator
method constructor (line 110) | constructor() {
method getDefaults (line 141) | static getDefaults(): PulseOscillatorOptions {
method _start (line 154) | protected _start(time: Time): void {
method _stop (line 163) | protected _stop(time: Time): void {
method _restart (line 172) | protected _restart(time: Seconds): void {
method phase (line 181) | get phase(): Degrees {
method phase (line 184) | set phase(phase: Degrees) {
method type (line 191) | get type(): "pulse" {
method baseType (line 198) | get baseType(): "pulse" {
method partials (line 205) | get partials(): number[] {
method partialCount (line 212) | get partialCount(): number {
method carrierType (line 221) | set carrierType(type: "triangle" | "sine") {
method asArray (line 225) | async asArray(length = 1024): Promise<Float32Array> {
method dispose (line 232) | dispose(): this {
FILE: Tone/source/oscillator/ToneOscillatorNode.ts
type ToneOscillatorNodeOptions (line 8) | interface ToneOscillatorNodeOptions extends OneShotSourceOptions {
class ToneOscillatorNode (line 20) | class ToneOscillatorNode extends OneShotSource<ToneOscillatorNodeOptions> {
method constructor (line 45) | constructor() {
method getDefaults (line 74) | static getDefaults(): ToneOscillatorNodeOptions {
method start (line 86) | start(time?: Time): this {
method _stopSource (line 94) | protected _stopSource(time?: Seconds): void {
method setPeriodicWave (line 102) | setPeriodicWave(periodicWave: PeriodicWave): this {
method type (line 110) | get type(): OscillatorType {
method type (line 113) | set type(type: OscillatorType) {
method dispose (line 120) | dispose(): this {
FILE: examples/js/components.js
function __webpack_require__ (line 6) | function __webpack_require__(moduleId) {
FILE: examples/js/tone-ui.js
function __webpack_require__ (line 16) | function __webpack_require__(moduleId) {
FILE: test/helper/Basic.ts
function BasicTests (line 20) | function BasicTests(Constr, ...args: any[]): void {
function warns (line 122) | async function warns(fn: (...args: any[]) => any): Promise<void> {
FILE: test/helper/CompareToFile.ts
function getBuffersToCompare (line 9) | async function getBuffersToCompare(
function CompareToFile (line 40) | async function CompareToFile(
FILE: test/helper/Connect.ts
function connectFrom (line 3) | function connectFrom(): Gain {
function connectTo (line 7) | function connectTo(): Gain {
function ConnectTest (line 11) | function ConnectTest(constr, ...args: any[]): void {
FILE: test/helper/ConstantOutput.ts
function ConstantOutput (line 9) | async function ConstantOutput(
FILE: test/helper/Dispose.ts
function isDisposed (line 1) | function isDisposed(instance): void {
FILE: test/helper/EffectTests.ts
function EffectTests (line 8) | function EffectTests(Constr, args?, before?): void {
FILE: test/helper/InstrumentTests.ts
function wait (line 10) | function wait(time) {
function InstrumentTest (line 14) | function InstrumentTest(
FILE: test/helper/MonophonicTests.ts
function MonophonicTest (line 5) | function MonophonicTest(Constr, note, constrArg?): void {
FILE: test/helper/Offline.ts
type ReturnFunction (line 7) | type ReturnFunction = (time: Seconds) => void;
function Offline (line 9) | async function Offline(
function whenBetween (line 56) | function whenBetween(
function atTime (line 68) | function atTime(
FILE: test/helper/OscillatorTests.ts
function OscillatorTests (line 6) | function OscillatorTests(Constr, args?): void {
FILE: test/helper/OutputAudio.ts
function OutputAudio (line 5) | function OutputAudio(callback): Promise<void> {
FILE: test/helper/PassAudio.ts
function PassAudio (line 11) | function PassAudio(
FILE: test/helper/SignalTests.ts
type ToneAudioNodeConstructor (line 8) | interface ToneAudioNodeConstructor {
function SignalConnectAndDisconnect (line 15) | function SignalConnectAndDisconnect(
FILE: test/helper/SourceTests.ts
function SourceTests (line 8) | function SourceTests(Constr, args?): void {
FILE: test/helper/StereoSignal.ts
function StereoSignal (line 4) | function StereoSignal(l: number, r: number): Merge {
FILE: test/helper/compare/Compare.ts
function compareSpectra (line 5) | function compareSpectra(
function compareSignals (line 26) | function compareSignals(
type BufferResponse (line 45) | interface BufferResponse {
type BufferResponseType (line 50) | type BufferResponseType = BufferResponse | void;
function getBuffersToCompare (line 52) | async function getBuffersToCompare(
function toFile (line 96) | async function toFile(
function toFileSignal (line 124) | async function toFileSignal(
FILE: test/helper/compare/OfflineRender.ts
function OfflineRender (line 3) | async function OfflineRender(
function PassesAudio (line 29) | async function PassesAudio(
function MakesSound (line 61) | async function MakesSound(
FILE: test/helper/compare/Plot.ts
function spectrogram (line 11) | function spectrogram(
function signal (line 47) | function signal(buffer: TestAudioBuffer | ToneAudioBuffer): HTMLElement {
FILE: test/helper/compare/Spectrum.ts
function analyze (line 9) | function analyze(buffer: TestAudioBuffer, fftSize = 256, hopSize = 128) {
FILE: test/helper/compare/TestAudioBuffer.ts
class TestAudioBuffer (line 5) | class TestAudioBuffer {
method fromUrl (line 6) | static async fromUrl(
method fromTone (line 22) | static fromTone(buffer: ToneAudioBuffer) {
method constructor (line 30) | constructor(buffer: AudioBuffer | TestAudioBuffer | ToneAudioBuffer) {
method numberOfChannels (line 43) | get numberOfChannels(): number {
method duration (line 50) | get duration(): number {
method length (line 57) | get length(): number {
method sampleRate (line 64) | get sampleRate(): number {
method toArray (line 71) | toArray(): Float32Array[] {
method toMono (line 89) | toMono(): TestAudioBuffer {
method getRmsAtTime (line 111) | getRmsAtTime(time: number): number[] | number {
method getValueAtTime (line 146) | getValueAtTime(time: number): number[] | number {
method getTimeOfFirstSound (line 165) | getTimeOfFirstSound(threshold = 1e-6): number {
method getTimeOfLastSound (line 182) | getTimeOfLastSound(threshold = 1e-6): number {
method max (line 198) | max(): number {
method min (line 209) | min(): number {
method value (line 221) | value(): number {
method isSilent (line 233) | isSilent(threshold = 1e-6): boolean {
method clone (line 244) | clone(): TestAudioBuffer {
method resample (line 253) | async resample(sampleRate: number): Promise<TestAudioBuffer> {
method toWav (line 288) | toWav(): ArrayBuffer {
method downloadWav (line 295) | downloadWav(filename = "test_audio"): void {
method forEach (line 306) | forEach(callback: (sample: number, time: number) => void): void {
method forEachBetween (line 313) | forEachBetween(
FILE: test/scripts/test_examples.mjs
function findExamples (line 9) | function findExamples(obj) {
function createFixtureFiles (line 44) | async function createFixtureFiles(examples) {
function main (line 65) | async function main() {
FILE: test/scripts/test_html.mjs
function createFixtureFiles (line 12) | async function createFixtureFiles(files) {
function main (line 45) | async function main() {
FILE: test/scripts/test_readme.mjs
function findScripts (line 12) | async function findScripts() {
function createFixtureFiles (line 19) | async function createFixtureFiles(scripts) {
function main (line 34) | async function main() {
FILE: test/scripts/utils.mjs
constant ROOT_DIR (line 8) | const ROOT_DIR = fileURLToPath(new URL("../..", import.meta.url)).slice(...
FILE: test/web-test-runner.config.js
constant BUILD_DIR (line 11) | const BUILD_DIR = resolve(__dirname, "../build/esm");
function getFilesInToneDir (line 13) | function getFilesInToneDir(dir) {
Condensed preview — 432 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,836K chars).
[
{
"path": ".github/CONTRIBUTING.md",
"chars": 1932,
"preview": "Bug fixes and contributions are welcome!\n\nIf you're looking for ideas for where to get started, consider jumping in on a"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 1256,
"preview": "---\nname: Bug report\nabout: Report an issue with Tone.js\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the bug**\n\n"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 888,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: feature request\nassignees: ''\n\n---\n\n"
},
{
"path": ".github/PULL_REQUEST_TEMPLATE.md",
"chars": 167,
"preview": "1. Please make all pull requests on the `dev` branch.\n2. Don't commit build files\n2. Try to get all [tests](https://gith"
},
{
"path": ".github/codecov.yml",
"chars": 90,
"preview": "coverage:\n status:\n project:\n default:\n target: auto\n threshold: 1%"
},
{
"path": ".github/workflows/stale.yml",
"chars": 948,
"preview": "name: \"Close stale issues and PRs\"\non:\n schedule:\n - cron: \"30 1 * * *\"\n\njobs:\n stale:\n runs-on: ubu"
},
{
"path": ".github/workflows/test.yml",
"chars": 6444,
"preview": "name: Tests\n\non:\n pull_request:\n types: [opened, reopened, synchronize]\n branches:\n - dev\n "
},
{
"path": ".gitignore",
"chars": 465,
"preview": ".DS_Store\n*.asd\n*.scssc\n*.sublime-workspace\n*.sublime-project\n\nnode_modules\n\nTODO.txt\nwiki\n\nexamples/scratch.html\nexampl"
},
{
"path": "CHANGELOG.md",
"chars": 25838,
"preview": "# 15.0.x\n\n- `set` in constructor even if AudioBuffer is not from std-audio-context ([0399687](https://github.com/Tonej"
},
{
"path": "LICENSE.md",
"chars": 1072,
"preview": "MIT License\n\nCopyright (c) 2014-2025 Yotam Mann\n\nPermission is hereby granted, free of charge, to any person obtaining a"
},
{
"path": "README.md",
"chars": 11321,
"preview": "# Tone.js\n\n[](https://codecov.io/gh/Tonejs/To"
},
{
"path": "Tone/classes.ts",
"chars": 249,
"preview": "export * from \"./component/index.js\";\nexport * from \"./core/index.js\";\nexport * from \"./effect/index.js\";\nexport * from "
},
{
"path": "Tone/component/analysis/Analyser.test.ts",
"chars": 1787,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { Noise } from \"../.."
},
{
"path": "Tone/component/analysis/Analyser.ts",
"chars": 4512,
"preview": "import { Gain } from \"../../core/context/Gain.js\";\nimport {\n\tInputNode,\n\tOutputNode,\n\tToneAudioNode,\n\tToneAudioNodeOptio"
},
{
"path": "Tone/component/analysis/DCMeter.test.ts",
"chars": 785,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { PassAudio } from \"."
},
{
"path": "Tone/component/analysis/DCMeter.ts",
"chars": 990,
"preview": "import { optionsFromArguments } from \"../../core/util/Defaults.js\";\nimport { MeterBase, MeterBaseOptions } from \"./Meter"
},
{
"path": "Tone/component/analysis/FFT.test.ts",
"chars": 1828,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { Noise } from \"../.."
},
{
"path": "Tone/component/analysis/FFT.ts",
"chars": 3006,
"preview": "import { ToneAudioNode } from \"../../core/context/ToneAudioNode.js\";\nimport { dbToGain } from \"../../core/type/Conversio"
},
{
"path": "Tone/component/analysis/Follower.test.ts",
"chars": 3864,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { Offline } from \"../"
},
{
"path": "Tone/component/analysis/Follower.ts",
"chars": 2200,
"preview": "import {\n\tInputNode,\n\tOutputNode,\n\tToneAudioNode,\n\tToneAudioNodeOptions,\n} from \"../../core/context/ToneAudioNode.js\";\ni"
},
{
"path": "Tone/component/analysis/Meter.test.ts",
"chars": 3141,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests, warns } from \"../../../test/helper/Basic.js\";\nimport { PassAudio } "
},
{
"path": "Tone/component/analysis/Meter.ts",
"chars": 4137,
"preview": "import { dbToGain, gainToDb } from \"../../core/type/Conversions.js\";\nimport { NormalRange } from \"../../core/type/Units."
},
{
"path": "Tone/component/analysis/MeterBase.ts",
"chars": 1069,
"preview": "import {\n\tInputNode,\n\tOutputNode,\n\tToneAudioNode,\n\tToneAudioNodeOptions,\n} from \"../../core/context/ToneAudioNode.js\";\ni"
},
{
"path": "Tone/component/analysis/Waveform.test.ts",
"chars": 1004,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { Noise } from \"../.."
},
{
"path": "Tone/component/analysis/Waveform.ts",
"chars": 1560,
"preview": "import { PowerOfTwo } from \"../../core/type/Units.js\";\nimport { optionsFromArguments } from \"../../core/util/Defaults.js"
},
{
"path": "Tone/component/channel/Channel.test.ts",
"chars": 2182,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { Offline } from \"../"
},
{
"path": "Tone/component/channel/Channel.ts",
"chars": 4494,
"preview": "import { Gain } from \"../../core/context/Gain.js\";\nimport { Param } from \"../../core/context/Param.js\";\nimport {\n\tInputN"
},
{
"path": "Tone/component/channel/CrossFade.test.ts",
"chars": 1703,
"preview": "import { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { connectFrom, connectTo } from \"../../../test/helper"
},
{
"path": "Tone/component/channel/CrossFade.ts",
"chars": 4844,
"preview": "import { Gain } from \"../../core/context/Gain.js\";\nimport {\n\tconnect,\n\tToneAudioNode,\n\tToneAudioNodeOptions,\n} from \"../"
},
{
"path": "Tone/component/channel/Merge.test.ts",
"chars": 1700,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { connectFrom, connec"
},
{
"path": "Tone/component/channel/Merge.ts",
"chars": 1700,
"preview": "import {\n\tToneAudioNode,\n\tToneAudioNodeOptions,\n} from \"../../core/context/ToneAudioNode.js\";\nimport { Positive } from \""
},
{
"path": "Tone/component/channel/MidSideMerge.test.ts",
"chars": 735,
"preview": "import { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { connectFrom, connectTo } from \"../../../test/helper"
},
{
"path": "Tone/component/channel/MidSideMerge.ts",
"chars": 2693,
"preview": "import { Gain } from \"../../core/context/Gain.js\";\nimport {\n\tToneAudioNode,\n\tToneAudioNodeOptions,\n} from \"../../core/co"
},
{
"path": "Tone/component/channel/MidSideSplit.test.ts",
"chars": 2581,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { connectFrom, connec"
},
{
"path": "Tone/component/channel/MidSideSplit.ts",
"chars": 2427,
"preview": "import {\n\tToneAudioNode,\n\tToneAudioNodeOptions,\n} from \"../../core/context/ToneAudioNode.js\";\nimport { optionsFromArgume"
},
{
"path": "Tone/component/channel/Mono.test.ts",
"chars": 1442,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { Offline } from \"../"
},
{
"path": "Tone/component/channel/Mono.ts",
"chars": 1327,
"preview": "import { Gain } from \"../../core/context/Gain.js\";\nimport {\n\tOutputNode,\n\tToneAudioNode,\n\tToneAudioNodeOptions,\n} from \""
},
{
"path": "Tone/component/channel/MultibandSplit.test.ts",
"chars": 1815,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { connectFrom, connec"
},
{
"path": "Tone/component/channel/MultibandSplit.ts",
"chars": 4130,
"preview": "import { Gain } from \"../../core/context/Gain.js\";\nimport {\n\tToneAudioNode,\n\tToneAudioNodeOptions,\n} from \"../../core/co"
},
{
"path": "Tone/component/channel/PanVol.test.ts",
"chars": 1496,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { Offline } from \"../"
},
{
"path": "Tone/component/channel/PanVol.ts",
"chars": 2548,
"preview": "import { Param } from \"../../core/context/Param.js\";\nimport {\n\tInputNode,\n\tOutputNode,\n\tToneAudioNode,\n\tToneAudioNodeOpt"
},
{
"path": "Tone/component/channel/Panner.test.ts",
"chars": 2551,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { Offline } from \"../"
},
{
"path": "Tone/component/channel/Panner.ts",
"chars": 2536,
"preview": "import { Param } from \"../../core/context/Param.js\";\nimport {\n\tToneAudioNode,\n\tToneAudioNodeOptions,\n} from \"../../core/"
},
{
"path": "Tone/component/channel/Panner3D.test.ts",
"chars": 2198,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { PassAudio } from \"."
},
{
"path": "Tone/component/channel/Panner3D.ts",
"chars": 5968,
"preview": "import \"../../core/context/Listener.js\";\n\nimport { Param } from \"../../core/context/Param.js\";\nimport {\n\tToneAudioNode,\n"
},
{
"path": "Tone/component/channel/Recorder.test.ts",
"chars": 3193,
"preview": "import { expect } from \"chai\";\n\nimport { connectFrom } from \"../../../test/helper/Connect.js\";\nimport { Context } from \""
},
{
"path": "Tone/component/channel/Recorder.ts",
"chars": 4739,
"preview": "import { theWindow } from \"../../core/context/AudioContext.js\";\nimport { Gain } from \"../../core/context/Gain.js\";\nimpor"
},
{
"path": "Tone/component/channel/Solo.test.ts",
"chars": 3821,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { ConstantOutput } fr"
},
{
"path": "Tone/component/channel/Solo.ts",
"chars": 3884,
"preview": "import { BaseContext } from \"../../core/context/BaseContext.js\";\nimport { Gain } from \"../../core/context/Gain.js\";\nimpo"
},
{
"path": "Tone/component/channel/Split.test.ts",
"chars": 2007,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { connectTo } from \"."
},
{
"path": "Tone/component/channel/Split.ts",
"chars": 1309,
"preview": "import {\n\tToneAudioNode,\n\tToneAudioNodeOptions,\n} from \"../../core/context/ToneAudioNode.js\";\nimport { optionsFromArgume"
},
{
"path": "Tone/component/channel/Volume.test.ts",
"chars": 3452,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { connectFrom, connec"
},
{
"path": "Tone/component/channel/Volume.ts",
"chars": 2556,
"preview": "import { Gain } from \"../../core/context/Gain.js\";\nimport { Param } from \"../../core/context/Param.js\";\nimport {\n\tToneAu"
},
{
"path": "Tone/component/dynamics/Compressor.test.ts",
"chars": 2420,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { PassAudio } from \"."
},
{
"path": "Tone/component/dynamics/Compressor.ts",
"chars": 4457,
"preview": "import { Param } from \"../../core/context/Param.js\";\nimport {\n\tToneAudioNode,\n\tToneAudioNodeOptions,\n} from \"../../core/"
},
{
"path": "Tone/component/dynamics/Gate.test.ts",
"chars": 1916,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { CompareToFile } fro"
},
{
"path": "Tone/component/dynamics/Gate.ts",
"chars": 3001,
"preview": "import { Gain } from \"../../core/context/Gain.js\";\nimport {\n\tToneAudioNode,\n\tToneAudioNodeOptions,\n} from \"../../core/co"
},
{
"path": "Tone/component/dynamics/Limiter.test.ts",
"chars": 1065,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { PassAudio } from \"."
},
{
"path": "Tone/component/dynamics/Limiter.ts",
"chars": 2198,
"preview": "import { Param } from \"../../core/context/Param.js\";\nimport {\n\tInputNode,\n\tOutputNode,\n\tToneAudioNode,\n\tToneAudioNodeOpt"
},
{
"path": "Tone/component/dynamics/MidSideCompressor.test.ts",
"chars": 1451,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { PassAudio } from \"."
},
{
"path": "Tone/component/dynamics/MidSideCompressor.ts",
"chars": 2626,
"preview": "import {\n\tInputNode,\n\tOutputNode,\n\tToneAudioNode,\n\tToneAudioNodeOptions,\n} from \"../../core/context/ToneAudioNode.js\";\ni"
},
{
"path": "Tone/component/dynamics/MultibandCompressor.test.ts",
"chars": 1424,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { PassAudio } from \"."
},
{
"path": "Tone/component/dynamics/MultibandCompressor.ts",
"chars": 3596,
"preview": "import { Gain } from \"../../core/context/Gain.js\";\nimport {\n\tInputNode,\n\tToneAudioNode,\n\tToneAudioNodeOptions,\n} from \"."
},
{
"path": "Tone/component/envelope/AmplitudeEnvelope.test.ts",
"chars": 2603,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { CompareToFile } fro"
},
{
"path": "Tone/component/envelope/AmplitudeEnvelope.ts",
"chars": 2373,
"preview": "import { Gain } from \"../../core/context/Gain.js\";\nimport { NormalRange, Time } from \"../../core/type/Units.js\";\nimport "
},
{
"path": "Tone/component/envelope/Envelope.test.ts",
"chars": 25245,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { connectTo } from \"."
},
{
"path": "Tone/component/envelope/Envelope.ts",
"chars": 18011,
"preview": "import { OfflineContext } from \"../../core/context/OfflineContext.js\";\nimport { InputNode, OutputNode } from \"../../core"
},
{
"path": "Tone/component/envelope/FrequencyEnvelope.test.ts",
"chars": 2561,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { connectFrom, connec"
},
{
"path": "Tone/component/envelope/FrequencyEnvelope.ts",
"chars": 3497,
"preview": "import { Frequency, Hertz, NormalRange, Time } from \"../../core/type/Units.js\";\nimport { assertRange } from \"../../core/"
},
{
"path": "Tone/component/filter/BiquadFilter.test.ts",
"chars": 2925,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { Offline } from \"../"
},
{
"path": "Tone/component/filter/BiquadFilter.ts",
"chars": 4971,
"preview": "import { Param } from \"../../core/context/Param.js\";\nimport {\n\tToneAudioNode,\n\tToneAudioNodeOptions,\n} from \"../../core/"
},
{
"path": "Tone/component/filter/Convolver.test.ts",
"chars": 2337,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { ToneAudioBuffer } f"
},
{
"path": "Tone/component/filter/Convolver.ts",
"chars": 3880,
"preview": "import { Gain } from \"../../core/context/Gain.js\";\nimport { ToneAudioBuffer } from \"../../core/context/ToneAudioBuffer.j"
},
{
"path": "Tone/component/filter/EQ3.test.ts",
"chars": 1448,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { PassAudio } from \"."
},
{
"path": "Tone/component/filter/EQ3.ts",
"chars": 3855,
"preview": "import { Gain } from \"../../core/context/Gain.js\";\nimport { Param } from \"../../core/context/Param.js\";\nimport {\n\tToneAu"
},
{
"path": "Tone/component/filter/FeedbackCombFilter.test.ts",
"chars": 2665,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { Offline } from \"../"
},
{
"path": "Tone/component/filter/FeedbackCombFilter.ts",
"chars": 3252,
"preview": "import { Gain } from \"../../core/context/Gain.js\";\nimport { Param } from \"../../core/context/Param.js\";\nimport {\n\tconnec"
},
{
"path": "Tone/component/filter/FeedbackCombFilter.worklet.ts",
"chars": 1070,
"preview": "import \"../../core/worklet/SingleIOProcessor.worklet.js\";\nimport \"../../core/worklet/DelayLine.worklet.js\";\n\nimport { re"
},
{
"path": "Tone/component/filter/Filter.test.ts",
"chars": 3474,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { Offline } from \"../"
},
{
"path": "Tone/component/filter/Filter.ts",
"chars": 6057,
"preview": "import { Gain } from \"../../core/context/Gain.js\";\nimport {\n\tconnectSeries,\n\tToneAudioNode,\n} from \"../../core/context/T"
},
{
"path": "Tone/component/filter/LowpassCombFilter.test.ts",
"chars": 2519,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { Offline } from \"../"
},
{
"path": "Tone/component/filter/LowpassCombFilter.ts",
"chars": 2751,
"preview": "import { Param } from \"../../core/context/Param.js\";\nimport {\n\tInputNode,\n\tOutputNode,\n\tToneAudioNode,\n\tToneAudioNodeOpt"
},
{
"path": "Tone/component/filter/OnePoleFilter.test.ts",
"chars": 2668,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { CompareToFile } fro"
},
{
"path": "Tone/component/filter/OnePoleFilter.ts",
"chars": 3963,
"preview": "import { Gain } from \"../../core/context/Gain.js\";\nimport {\n\tToneAudioNode,\n\tToneAudioNodeOptions,\n} from \"../../core/co"
},
{
"path": "Tone/component/filter/PhaseShiftAllpass.test.ts",
"chars": 2690,
"preview": "import { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { CompareToFile } from \"../../../test/helper/CompareT"
},
{
"path": "Tone/component/filter/PhaseShiftAllpass.ts",
"chars": 2630,
"preview": "import { Gain } from \"../../core/context/Gain.js\";\nimport {\n\tconnectSeries,\n\tToneAudioNode,\n\tToneAudioNodeOptions,\n} fro"
},
{
"path": "Tone/component/index.ts",
"chars": 1414,
"preview": "export * from \"./analysis/Analyser.js\";\nexport * from \"./analysis/DCMeter.js\";\nexport * from \"./analysis/FFT.js\";\nexport"
},
{
"path": "Tone/core/Global.ts",
"chars": 2395,
"preview": "import { version } from \"../version.js\";\nimport {\n\tAnyAudioContext,\n\thasAudioContext,\n\ttheWindow,\n} from \"./context/Audi"
},
{
"path": "Tone/core/Tone.ts",
"chars": 2454,
"preview": "/**\n * Tone.js\n * @author Yotam Mann\n * @license http://opensource.org/licenses/MIT MIT License\n * @copyright 2014-2024 "
},
{
"path": "Tone/core/clock/Clock.test.ts",
"chars": 18674,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { atTime, Offline, wh"
},
{
"path": "Tone/core/clock/Clock.ts",
"chars": 9077,
"preview": "import {\n\tToneWithContext,\n\tToneWithContextOptions,\n} from \"../context/ToneWithContext.js\";\nimport { Frequency, Hertz, S"
},
{
"path": "Tone/core/clock/TickParam.test.ts",
"chars": 357,
"preview": "import { BasicTests, testAudioContext } from \"../../../test/helper/Basic.js\";\n// import { atTime, Offline } from \"../../"
},
{
"path": "Tone/core/clock/TickParam.ts",
"chars": 9538,
"preview": "import { AutomationEvent, Param, ParamOptions } from \"../context/Param.js\";\nimport { Seconds, Ticks, Time, UnitMap, Unit"
},
{
"path": "Tone/core/clock/TickSignal.test.ts",
"chars": 19294,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { Offline } from \"../"
},
{
"path": "Tone/core/clock/TickSignal.ts",
"chars": 2615,
"preview": "import { Signal, SignalOptions } from \"../../signal/Signal.js\";\nimport { InputNode } from \"../context/ToneAudioNode.js\";"
},
{
"path": "Tone/core/clock/TickSource.test.ts",
"chars": 25124,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { Offline } from \"../"
},
{
"path": "Tone/core/clock/TickSource.ts",
"chars": 12981,
"preview": "import {\n\tToneWithContext,\n\tToneWithContextOptions,\n} from \"../context/ToneWithContext.js\";\nimport { Seconds, Ticks, Tim"
},
{
"path": "Tone/core/clock/Ticker.test.ts",
"chars": 2002,
"preview": "import { expect } from \"chai\";\n\nimport { Ticker } from \"./Ticker.js\";\n\ndescribe(\"Ticker\", () => {\n\tfunction empty(): voi"
},
{
"path": "Tone/core/clock/Ticker.ts",
"chars": 3437,
"preview": "import { Seconds } from \"../type/Units.js\";\n\nexport type TickerClockSource = \"worker\" | \"timeout\" | \"offline\";\n\n/**\n * A"
},
{
"path": "Tone/core/clock/Transport.test.ts",
"chars": 30237,
"preview": "// importing for side affects\nimport \"../context/Destination.js\";\n\nimport { expect } from \"chai\";\n\nimport { warns } from"
},
{
"path": "Tone/core/clock/Transport.ts",
"chars": 23103,
"preview": "import { ToneAudioNode } from \"../../core/context/ToneAudioNode.js\";\nimport { TimeClass } from \"../../core/type/Time.js\""
},
{
"path": "Tone/core/clock/TransportEvent.test.ts",
"chars": 1118,
"preview": "import { expect } from \"chai\";\n\nimport { Offline } from \"../../../test/helper/Offline.js\";\nimport { TransportInstance } "
},
{
"path": "Tone/core/clock/TransportEvent.ts",
"chars": 2293,
"preview": "import { Seconds, Ticks } from \"../type/Units.js\";\nimport { noOp } from \"../util/Interface.js\";\nimport type { TransportI"
},
{
"path": "Tone/core/clock/TransportRepeatEvent.test.ts",
"chars": 1145,
"preview": "import { expect } from \"chai\";\n\nimport { Offline } from \"../../../test/helper/Offline.js\";\nimport { TransportInstance } "
},
{
"path": "Tone/core/clock/TransportRepeatEvent.ts",
"chars": 4150,
"preview": "import { BaseContext } from \"../context/BaseContext.js\";\nimport { TicksClass } from \"../type/Ticks.js\";\nimport { Seconds"
},
{
"path": "Tone/core/context/AbstractParam.ts",
"chars": 9746,
"preview": "import { Time, UnitMap, UnitName } from \"../type/Units.js\";\n\n/**\n * Abstract base class for {@link Param} and {@link Sig"
},
{
"path": "Tone/core/context/AudioContext.ts",
"chars": 2178,
"preview": "import {\n\tAudioContext as stdAudioContext,\n\tAudioWorkletNode as stdAudioWorkletNode,\n\tOfflineAudioContext as stdOfflineA"
},
{
"path": "Tone/core/context/BaseContext.ts",
"chars": 4176,
"preview": "import type { TransportInstance as Transport } from \"../clock/Transport.js\";\nimport { Seconds } from \"../type/Units.js\";"
},
{
"path": "Tone/core/context/Context.test.ts",
"chars": 9458,
"preview": "import { expect } from \"chai\";\n\nimport { ConstantOutput } from \"../../../test/helper/ConstantOutput.js\";\nimport { Offlin"
},
{
"path": "Tone/core/context/Context.ts",
"chars": 17002,
"preview": "import { Ticker, TickerClockSource } from \"../clock/Ticker.js\";\nimport type { TransportInstance as Transport } from \"../"
},
{
"path": "Tone/core/context/ContextInitialization.ts",
"chars": 1076,
"preview": "//-------------------------------------\n// INITIALIZING NEW CONTEXT\n//-------------------------------------\nimport type "
},
{
"path": "Tone/core/context/Delay.test.ts",
"chars": 2763,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { connectFrom, connec"
},
{
"path": "Tone/core/context/Delay.ts",
"chars": 2888,
"preview": "import { Param } from \"../context/Param.js\";\nimport { Seconds, Time } from \"../type/Units.js\";\nimport { optionsFromArgum"
},
{
"path": "Tone/core/context/Destination.test.ts",
"chars": 2309,
"preview": "import { expect } from \"chai\";\n\nimport { warns } from \"../../../test/helper/Basic.js\";\nimport { Offline } from \"../../.."
},
{
"path": "Tone/core/context/Destination.ts",
"chars": 3816,
"preview": "import { Volume } from \"../../component/channel/Volume.js\";\nimport { Decibels } from \"../type/Units.js\";\nimport { option"
},
{
"path": "Tone/core/context/DummyContext.test.ts",
"chars": 1331,
"preview": "import { DummyContext } from \"./DummyContext.js\";\n\ndescribe(\"DummyContext\", () => {\n\tit(\"has all the methods and members"
},
{
"path": "Tone/core/context/DummyContext.ts",
"chars": 4116,
"preview": "import type { TransportInstance as Transport } from \"../clock/Transport.js\";\nimport { Seconds } from \"../type/Units.js\";"
},
{
"path": "Tone/core/context/Gain.test.ts",
"chars": 1977,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { connectFrom, connec"
},
{
"path": "Tone/core/context/Gain.ts",
"chars": 2495,
"preview": "import { Param } from \"../context/Param.js\";\nimport { UnitMap, UnitName } from \"../type/Units.js\";\nimport { optionsFromA"
},
{
"path": "Tone/core/context/Listener.test.ts",
"chars": 734,
"preview": "import { expect } from \"chai\";\n\nimport { Offline } from \"../../../test/helper/Offline.js\";\nimport { getContext } from \"."
},
{
"path": "Tone/core/context/Listener.ts",
"chars": 2844,
"preview": "import { onContextClose, onContextInit } from \"./ContextInitialization.js\";\nimport { Param } from \"./Param.js\";\nimport {"
},
{
"path": "Tone/core/context/Offline.test.ts",
"chars": 1993,
"preview": "import { expect } from \"chai\";\n\nimport { TestAudioBuffer } from \"../../../test/helper/compare/TestAudioBuffer.js\";\nimpor"
},
{
"path": "Tone/core/context/Offline.ts",
"chars": 2386,
"preview": "import \"./Destination.js\";\nimport \"./Listener.js\";\n\nimport { getContext, setContext } from \"../Global.js\";\nimport { Seco"
},
{
"path": "Tone/core/context/OfflineContext.test.ts",
"chars": 1778,
"preview": "import { expect } from \"chai\";\n\nimport { OfflineContext } from \"./OfflineContext.js\";\n\ncontext(\"OfflineContext\", () => {"
},
{
"path": "Tone/core/context/OfflineContext.ts",
"chars": 3146,
"preview": "import { createOfflineAudioContext } from \"../context/AudioContext.js\";\nimport { Context } from \"../context/Context.js\";"
},
{
"path": "Tone/core/context/OnRunning.test.ts",
"chars": 1399,
"preview": "import { expect } from \"chai\";\n\nimport { Context } from \"./Context.js\";\nimport { OfflineContext } from \"./OfflineContext"
},
{
"path": "Tone/core/context/OnRunning.ts",
"chars": 781,
"preview": "import { BaseContext } from \"./BaseContext.js\";\n\n/**\n * Invoked when the context is started. The callback is invoked imm"
},
{
"path": "Tone/core/context/Param.test.ts",
"chars": 20144,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests, testAudioContext } from \"../../../test/helper/Basic.js\";\nimport { P"
},
{
"path": "Tone/core/context/Param.ts",
"chars": 18820,
"preview": "import { AbstractParam } from \"../context/AbstractParam.js\";\nimport { dbToGain, gainToDb } from \"../type/Conversions.js\""
},
{
"path": "Tone/core/context/ToneAudioBuffer.test.ts",
"chars": 12672,
"preview": "import { expect } from \"chai\";\n\nimport { getContext } from \"../Global.js\";\nimport { ToneAudioBuffer } from \"./ToneAudioB"
},
{
"path": "Tone/core/context/ToneAudioBuffer.ts",
"chars": 11191,
"preview": "import { getContext } from \"../Global.js\";\nimport { Tone } from \"../Tone.js\";\nimport { Samples, Seconds } from \"../type/"
},
{
"path": "Tone/core/context/ToneAudioBuffers.test.ts",
"chars": 3874,
"preview": "import { expect } from \"chai\";\n\nimport { ToneAudioBuffer } from \"./ToneAudioBuffer.js\";\nimport { ToneAudioBuffers } from"
},
{
"path": "Tone/core/context/ToneAudioBuffers.ts",
"chars": 4617,
"preview": "import { Tone } from \"../Tone.js\";\nimport { assert } from \"../util/Debug.js\";\nimport { optionsFromArguments } from \"../u"
},
{
"path": "Tone/core/context/ToneAudioNode.test.ts",
"chars": 9117,
"preview": "import { expect } from \"chai\";\n\nimport { Offline } from \"../../../test/helper/Offline.js\";\nimport { PassAudio } from \".."
},
{
"path": "Tone/core/context/ToneAudioNode.ts",
"chars": 11983,
"preview": "import { isAudioNode, isAudioParam } from \"../util/AdvancedTypeCheck.js\";\nimport { assert, warn } from \"../util/Debug.js"
},
{
"path": "Tone/core/context/ToneWithContext.test.ts",
"chars": 2210,
"preview": "import { expect } from \"chai\";\n\nimport { Offline } from \"../../../test/helper/Offline.js\";\nimport { getContext } from \"."
},
{
"path": "Tone/core/context/ToneWithContext.ts",
"chars": 6600,
"preview": "import { getContext } from \"../Global.js\";\nimport { Tone } from \"../Tone.js\";\nimport { FrequencyClass } from \"../type/Fr"
},
{
"path": "Tone/core/index.ts",
"chars": 1242,
"preview": "export * from \"./clock/Clock.js\";\nexport * from \"./context/BaseContext.js\";\nexport * from \"./context/Context.js\";\nexport"
},
{
"path": "Tone/core/type/Conversions.test.ts",
"chars": 1182,
"preview": "import { expect } from \"chai\";\n\nimport {\n\tdbToGain,\n\tequalPowerScale,\n\tgainToDb,\n\tintervalToFrequencyRatio,\n} from \"./Co"
},
{
"path": "Tone/core/type/Conversions.ts",
"chars": 1968,
"preview": "import {\n\tDecibels,\n\tGainFactor,\n\tHertz,\n\tInterval,\n\tMidiNote,\n\tNormalRange,\n} from \"./Units.js\";\n\n/**\n * Equal power ga"
},
{
"path": "Tone/core/type/Frequency.test.ts",
"chars": 9045,
"preview": "import { expect } from \"chai\";\nimport { Midi as TonalMidi, Note } from \"tonal\";\n\nimport { BasicTests } from \"../../../te"
},
{
"path": "Tone/core/type/Frequency.ts",
"chars": 7108,
"preview": "import { getContext } from \"../Global.js\";\nimport { intervalToFrequencyRatio, mtof } from \"./Conversions.js\";\nimport { f"
},
{
"path": "Tone/core/type/Midi.test.ts",
"chars": 4585,
"preview": "import { expect } from \"chai\";\nimport { Midi as TonalMidi } from \"tonal\";\n\nimport { BasicTests } from \"../../../test/hel"
},
{
"path": "Tone/core/type/Midi.ts",
"chars": 2140,
"preview": "import { getContext } from \"../Global.js\";\nimport { ftom, mtof } from \"./Conversions.js\";\nimport { FrequencyClass, Frequ"
},
{
"path": "Tone/core/type/NoteUnits.ts",
"chars": 743,
"preview": "// This file contains all of the valid note names for all pitches between C-4 and C11\n\ntype Letter = \"C\" | \"D\" | \"E\" | \""
},
{
"path": "Tone/core/type/Ticks.test.ts",
"chars": 6142,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { atTime, Offline } f"
},
{
"path": "Tone/core/type/Ticks.ts",
"chars": 1688,
"preview": "import { getContext } from \"../Global.js\";\nimport { TimeBaseUnit, TimeValue } from \"./TimeBase.js\";\nimport { TransportTi"
},
{
"path": "Tone/core/type/Time.test.ts",
"chars": 5974,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { atTime, Offline } f"
},
{
"path": "Tone/core/type/Time.ts",
"chars": 5316,
"preview": "import { getContext } from \"../Global.js\";\nimport { ftom } from \"./Conversions.js\";\nimport {\n\tTimeBaseClass,\n\tTimeBaseUn"
},
{
"path": "Tone/core/type/TimeBase.ts",
"chars": 7687,
"preview": "import { BaseContext } from \"../context/BaseContext.js\";\nimport { Tone } from \"../Tone.js\";\nimport { isDefined, isObject"
},
{
"path": "Tone/core/type/TransportTime.test.ts",
"chars": 5780,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { atTime, Offline } f"
},
{
"path": "Tone/core/type/TransportTime.ts",
"chars": 1271,
"preview": "import { getContext } from \"../Global.js\";\nimport { Seconds, Ticks } from \"../type/Units.js\";\nimport { TimeClass } from "
},
{
"path": "Tone/core/type/Units.ts",
"chars": 5197,
"preview": "export * from \"./NoteUnits.js\";\n\nimport { Note } from \"./NoteUnits.js\";\n\n/**\n * A number representing a time in seconds\n"
},
{
"path": "Tone/core/util/AdvancedTypeCheck.ts",
"chars": 947,
"preview": "import {\n\tAudioBuffer,\n\tisAnyAudioContext,\n\tisAnyAudioNode,\n\tisAnyAudioParam,\n\tisAnyOfflineAudioContext,\n} from \"standar"
},
{
"path": "Tone/core/util/Debug.test.ts",
"chars": 1927,
"preview": "import { expect } from \"chai\";\n\nimport { Oscillator } from \"../../source/index.js\";\nimport { ToneOscillatorNode } from \""
},
{
"path": "Tone/core/util/Debug.ts",
"chars": 2315,
"preview": "import type { BaseContext } from \"../context/BaseContext.js\";\nimport type { Time } from \"../type/Units.js\";\nimport { isU"
},
{
"path": "Tone/core/util/Decorator.ts",
"chars": 1159,
"preview": "import { Time } from \"../type/Units.js\";\nimport { assertRange } from \"./Debug.js\";\n\n/**\n * Assert that the number is in "
},
{
"path": "Tone/core/util/Defaults.ts",
"chars": 3560,
"preview": "import type { BaseToneOptions } from \"../Tone.js\";\nimport {\n\tisAudioBuffer,\n\tisAudioNode,\n\tisAudioParam,\n} from \"./Advan"
},
{
"path": "Tone/core/util/Draw.test.ts",
"chars": 1961,
"preview": "import { expect } from \"chai\";\n\nimport { DrawInstance } from \"./Draw.js\";\n\ndescribe(\"Draw\", () => {\n\tconst originalRAF ="
},
{
"path": "Tone/core/util/Draw.ts",
"chars": 3409,
"preview": "import {\n\tonContextClose,\n\tonContextInit,\n} from \"../context/ContextInitialization.js\";\nimport {\n\tToneWithContext,\n\tTone"
},
{
"path": "Tone/core/util/Emitter.test.ts",
"chars": 2658,
"preview": "import { expect } from \"chai\";\n\nimport { Emitter } from \"./Emitter.js\";\n\ndescribe(\"Emitter\", () => {\n\tit(\"can be created"
},
{
"path": "Tone/core/util/Emitter.ts",
"chars": 3403,
"preview": "import { Tone } from \"../Tone.js\";\nimport { isUndef } from \"./TypeCheck.js\";\n\nexport interface EmitterEventObject {\n\t[ev"
},
{
"path": "Tone/core/util/Interface.ts",
"chars": 1198,
"preview": "import { isArray } from \"./TypeCheck.js\";\n\n// return an interface which excludes certain keys\nexport type Omit<T, K exte"
},
{
"path": "Tone/core/util/IntervalTimeline.test.ts",
"chars": 10759,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../../test/helper/Basic.js\";\nimport { IntervalTimeline, I"
},
{
"path": "Tone/core/util/IntervalTimeline.ts",
"chars": 13615,
"preview": "import { Tone } from \"../Tone.js\";\nimport { assert } from \"./Debug.js\";\nimport { isDefined } from \"./TypeCheck.js\";\n\n/**"
},
{
"path": "Tone/core/util/Math.ts",
"chars": 832,
"preview": "/**\n * The threshold for correctness for operators. Less than one sample even\n * at very high sampling rates (e.g. `1e-6"
},
{
"path": "Tone/core/util/StateTimeline.test.ts",
"chars": 3323,
"preview": "import { expect } from \"chai\";\n\nimport { StateTimeline } from \"./StateTimeline.js\";\n\ndescribe(\"StateTimeline\", () => {\n\t"
},
{
"path": "Tone/core/util/StateTimeline.ts",
"chars": 2829,
"preview": "import { Seconds } from \"../type/Units.js\";\nimport { assertRange } from \"./Debug.js\";\nimport { Timeline, TimelineEvent }"
},
{
"path": "Tone/core/util/Timeline.test.ts",
"chars": 13776,
"preview": "import { expect } from \"chai\";\n\nimport { Timeline } from \"./Timeline.js\";\n\ninterface StateTimelineEvent {\n\tstate: string"
},
{
"path": "Tone/core/util/Timeline.ts",
"chars": 11334,
"preview": "import { Tone } from \"../Tone.js\";\nimport { Seconds } from \"../type/Units.js\";\nimport { assert } from \"./Debug.js\";\nimpo"
},
{
"path": "Tone/core/util/TimelineValue.test.ts",
"chars": 753,
"preview": "import { expect } from \"chai\";\n\nimport { TimelineValue } from \"./TimelineValue.js\";\n\ndescribe(\"TimelineValue\", () => {\n\t"
},
{
"path": "Tone/core/util/TimelineValue.ts",
"chars": 1157,
"preview": "import { Tone } from \"../Tone.js\";\nimport { Seconds } from \"../type/Units.js\";\nimport { Timeline, TimelineEvent } from \""
},
{
"path": "Tone/core/util/TypeCheck.ts",
"chars": 1472,
"preview": "import { Note } from \"../type/Units.js\";\n\n/**\n * Test if the arg is undefined\n */\nexport function isUndef(arg: unknown):"
},
{
"path": "Tone/core/util/global.d.ts",
"chars": 300,
"preview": "/**\n * Replace the default lib.dom.d.ts interface to reflect the fact\n * that the AudioParamMap extends Map\n */\ninterfac"
},
{
"path": "Tone/core/worklet/DelayLine.worklet.ts",
"chars": 1793,
"preview": "import { addToWorklet } from \"./WorkletGlobalScope.js\";\n\nconst delayLine = /* javascript */ `\n\t/**\n\t * A multichannel bu"
},
{
"path": "Tone/core/worklet/SingleIOProcessor.worklet.ts",
"chars": 2101,
"preview": "import \"./ToneAudioWorkletProcessor.worklet.js\";\n\nimport { addToWorklet } from \"./WorkletGlobalScope.js\";\n\nexport const "
},
{
"path": "Tone/core/worklet/ToneAudioWorklet.ts",
"chars": 2548,
"preview": "import {\n\tToneAudioNode,\n\tToneAudioNodeOptions,\n} from \"../context/ToneAudioNode.js\";\nimport { noOp } from \"../util/Inte"
},
{
"path": "Tone/core/worklet/ToneAudioWorkletProcessor.worklet.ts",
"chars": 811,
"preview": "import { addToWorklet } from \"./WorkletGlobalScope.js\";\n\nconst toneAudioWorkletProcessor = /* javascript */ `\n\t/**\n\t * T"
},
{
"path": "Tone/core/worklet/WorkletGlobalScope.ts",
"chars": 752,
"preview": "/**\n * All of the classes or functions which are loaded into the AudioWorkletGlobalScope\n */\nconst workletContext: Set<s"
},
{
"path": "Tone/effect/AutoFilter.test.ts",
"chars": 3460,
"preview": "import { expect } from \"chai\";\nimport { Note } from \"tonal\";\n\nimport { BasicTests } from \"../../test/helper/Basic.js\";\ni"
},
{
"path": "Tone/effect/AutoFilter.ts",
"chars": 2786,
"preview": "import { Filter, FilterOptions } from \"../component/filter/Filter.js\";\nimport { Frequency, Positive } from \"../core/type"
},
{
"path": "Tone/effect/AutoPanner.test.ts",
"chars": 2744,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../test/helper/Basic.js\";\nimport { CompareToFile } from \""
},
{
"path": "Tone/effect/AutoPanner.ts",
"chars": 1694,
"preview": "import { Panner } from \"../component/channel/Panner.js\";\nimport { Frequency } from \"../core/type/Units.js\";\nimport { opt"
},
{
"path": "Tone/effect/AutoWah.test.ts",
"chars": 1760,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../test/helper/Basic.js\";\nimport { CompareToFile } from \""
},
{
"path": "Tone/effect/AutoWah.ts",
"chars": 5509,
"preview": "import { Follower } from \"../component/analysis/Follower.js\";\nimport { Filter } from \"../component/filter/Filter.js\";\nim"
},
{
"path": "Tone/effect/BitCrusher.test.ts",
"chars": 1516,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../test/helper/Basic.js\";\nimport { CompareToFile } from \""
},
{
"path": "Tone/effect/BitCrusher.ts",
"chars": 3411,
"preview": "import { Gain } from \"../core/context/Gain.js\";\nimport { Param } from \"../core/context/Param.js\";\nimport { connectSeries"
},
{
"path": "Tone/effect/BitCrusher.worklet.ts",
"chars": 673,
"preview": "import \"../core/worklet/SingleIOProcessor.worklet.js\";\n\nimport { registerProcessor } from \"../core/worklet/WorkletGlobal"
},
{
"path": "Tone/effect/Chebyshev.test.ts",
"chars": 1220,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../test/helper/Basic.js\";\nimport { CompareToFile } from \""
},
{
"path": "Tone/effect/Chebyshev.ts",
"chars": 3354,
"preview": "import { Positive } from \"../core/type/Units.js\";\nimport { assert } from \"../core/util/Debug.js\";\nimport { optionsFromAr"
},
{
"path": "Tone/effect/Chorus.test.ts",
"chars": 2448,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../test/helper/Basic.js\";\nimport { CompareToFile } from \""
},
{
"path": "Tone/effect/Chorus.ts",
"chars": 5803,
"preview": "import { Delay } from \"../core/context/Delay.js\";\nimport {\n\tDegrees,\n\tFrequency,\n\tMilliseconds,\n\tNormalRange,\n\tSeconds,\n"
},
{
"path": "Tone/effect/Distortion.test.ts",
"chars": 1101,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../test/helper/Basic.js\";\nimport { CompareToFile } from \""
},
{
"path": "Tone/effect/Distortion.ts",
"chars": 2445,
"preview": "import { optionsFromArguments } from \"../core/util/Defaults.js\";\nimport { WaveShaper } from \"../signal/WaveShaper.js\";\ni"
},
{
"path": "Tone/effect/Effect.ts",
"chars": 2403,
"preview": "import { CrossFade } from \"../component/channel/CrossFade.js\";\nimport { Gain } from \"../core/context/Gain.js\";\nimport {\n"
},
{
"path": "Tone/effect/FeedbackDelay.test.ts",
"chars": 2490,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../test/helper/Basic.js\";\nimport { CompareToFile } from \""
},
{
"path": "Tone/effect/FeedbackDelay.ts",
"chars": 2033,
"preview": "import { Delay } from \"../core/context/Delay.js\";\nimport { Param } from \"../core/context/Param.js\";\nimport { NormalRange"
},
{
"path": "Tone/effect/FeedbackEffect.ts",
"chars": 1707,
"preview": "import { Gain } from \"../core/context/Gain.js\";\nimport { Param } from \"../core/context/Param.js\";\nimport { NormalRange }"
},
{
"path": "Tone/effect/Freeverb.test.ts",
"chars": 1266,
"preview": "import { expect } from \"chai\";\n\nimport { BasicTests } from \"../../test/helper/Basic.js\";\nimport { CompareToFile } from \""
},
{
"path": "Tone/effect/Freeverb.ts",
"chars": 4203,
"preview": "import { LowpassCombFilter } from \"../component/filter/LowpassCombFilter.js\";\nimport { Frequency, NormalRange } from \".."
}
]
// ... and 232 more files (download for full content)
About this extraction
This page contains the full source code of the Tonejs/Tone.js GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 432 files (2.4 MB), approximately 660.1k tokens, and a symbol index with 2170 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.