Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Tone.js Audio Context instanceof AudioContext returns false #1298

Open
mageeagle opened this issue Dec 6, 2024 · 5 comments
Open

Tone.js Audio Context instanceof AudioContext returns false #1298

mageeagle opened this issue Dec 6, 2024 · 5 comments

Comments

@mageeagle
Copy link

mageeagle commented Dec 6, 2024

Describe the bug

I'm using this library https://github.com/GoogleChrome/omnitone to create an ambisonic decoder in the Tone.js AudioContext and it fails. Upon looking the code of the library I found that it uses instanceof to check and make sure it's an "AudioContext"
I'm using version Tone.js 15.1.3

Utils.isAudioContext = function(context) {
  return context instanceof AudioContext ||
    context instanceof OfflineAudioContext;
};

Tone.js context does not return true in when it's tested if it's a prototype of AudioContext

To Reproduce

I tried to run the following, and they all return false

Tone.getContext() instanceof AudioContext // false
Tone.getContext() instanceof OfflineAudioContext // false
Tone.getContext() instanceof BaseAudioContext // false

Expected behavior
The above should return true so it is recognized as an AudioContext

What I've tried
I thought it was an issue with standardized-audio-context, but I tried passing the AudioContext created directly from standardized-audio-context and it works. Then I went on to pass the new context to Tone.js, but I had to ignore the typescript error there. (This might be another issue?)

import { AudioContext } from 'standardized-audio-context';
const context = new AudioContext();
console.log(context instanceof AudioContext) // true

// No overload matches this call.
// Overload 1 of 2, '(context?: AnyAudioContext | undefined): Context', gave the following error.
// Argument of type 'IAudioContext' is not assignable to parameter of type 'AnyAudioContext | undefined'.
//  Type 'IAudioContext' is missing the following properties from type 'AudioContext': outputLatency, getOutputTimestamp, createScriptProcessor
//  Overload 2 of 2, '(options?: Partial<ContextOptions> | undefined): Context', gave the following error.
//   Type 'IAudioContext' has no properties in common with type 'Partial<ContextOptions>'.ts(2769)

//@ts-ignore
const toneContext = new Tone.Context(context);
Tone.setContext(toneContext, true);

Thanks.

@marcelblum
Copy link
Contributor

You probably want rawContext or in some cases rawContext._nativeAudioContext. Tone.getContext() gets you a Tone-wrapped context which is not the same as the native context that is an instance of AudioContext.

@mageeagle
Copy link
Author

Sorry, I forgot to mentioned I did try rawContext as well

Tone.getContext().rawContext instanceof AudioContext // false
Tone.getContext().rawContext instanceof OfflineAudioContext // false
Tone.getContext().rawContext instanceof BaseAudioContext // false

Doesn't work either

@marcelblum
Copy link
Contributor

If I go to https://tonejs.github.io/ and put Tone.getContext().rawContext._nativeAudioContext instanceof AudioContext in the dev console it returns true on every desktop browser I've tried it on

@mageeagle
Copy link
Author

mageeagle commented Dec 6, 2024

Thanks for the tip.
So Tone.getContext().rawContext._nativeAudioContext passes the check.
However, the Players / Gain nodes from Tone.js were not able to connect to the decoder initiated by the library mentioned above, giving an error: InvalidAccessError when I use the default Tone.js AudioContext

Because I needed to create a new context anyways with 48000Hz sample rate, I tried creating a new Context from Tone.js
const context = new Tone.Context(new Tone.context.rawContext.constructor({ sampleRate: 48000 }))
as suggested from here: #810

Typescript complains:

'context' is deprecated.ts(6385)
index.d.ts(82, 4): The declaration was marked as deprecated here.
This expression is not constructable.
Type 'Function' has no construct signatures.ts(2351)

Bypassing this error still creates the new context tho.
Using Tone.getContext().rawContext._nativeAudioContext after the creation of the new context gives the same InvalidAccessError when connecting to other Tone.js objects

const context = new Tone.Context(new Tone.context.rawContext.constructor({ sampleRate: 48000 }))
Tone.setContext(context, true);

// InvalidAccessError
const decoder = Omnitone.createHOARenderer(Tone.getContext().rawContext._nativeAudioContext, { ambisonicOrder: 2 })
Tone.connect(merge, decoder.input);
Tone.connect(decoder.output, gain);

However, weird enough, Tone.getContext().rawContext works, ONLY when I create a new context with a specified rawContext.
It doesn't work if I simply create a new Tone.Context

const context = new Tone.Context(new Tone.context.rawContext.constructor({ sampleRate: 48000 }))
Tone.setContext(context, true);

// No Errors, Sound working
const decoder = Omnitone.createHOARenderer(Tone.getContext().rawContext, { ambisonicOrder: 2 })
Tone.connect(merge, decoder.input);
Tone.connect(decoder.output, gain);

Anyways, it's working, but the behaviour mentioned above is kind of weird

@mageeagle
Copy link
Author

An update on the issue, the above solutions no longer work for some reason that I could not fathom.

Creating new a standardized-audio-context, or a rawContext constructor, annd passing the new context to instanceof AudioContext no longer returns true, but false.

Tone.getContext().rawContext._nativeAudioContext, as mentioned above, does not work and throws the InvalidAccessError Error, hinting that the audio nodes for some reason are created in different contexts and could not be connected.

The deployed versions of the site which worked before, now fails with the same error, so it shouldn't be a version upgrade issue.
I'll open an issue over at standardized-audio-context and see if they have an idea what's going on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants