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

not require audiolet instance passed to all new objects #39

Open
kn0ll opened this issue Sep 7, 2012 · 8 comments
Open

not require audiolet instance passed to all new objects #39

kn0ll opened this issue Sep 7, 2012 · 8 comments

Comments

@kn0ll
Copy link

kn0ll commented Sep 7, 2012

don't worry- last one for now. i realize this one is a bit more difficult, but i wouldn't think it's impossible to remove the necessity to pass an Audiolet instance to everything you create.

since i think you can only safely make one instance of sink.js, one way to achieve this would just have scheduler, device, etc set as globals, and pass sampleRate through generate(). i haven't thought about it too much and surely this isn't a good solution... but just to get the ball rolling...

your thoughts?

@oampo
Copy link
Owner

oampo commented Sep 10, 2012

Yeah, this is a bit ugly - I go back and forth over how the right way to do this is. I don't really want to have to pass sampleRate around all the time. Possibly what should happen is that the Audiolet object is should be a singleton, which the nodes can grab if they need the sample rate, scheduler, graph etc. That does seem a little bit close to just having a massive global though.

I think that any changes to this will wait until a good sized rewrite of the code takes place (I have vague plans for Audiolet 2), as IMO the API win from this is negated by losing compatibility with existing code. Will leave the issue open for now though and have a think about it.

@mattdiamond
Copy link

Wouldn't it be easiest to have all object creation occur through the instantiated Audiolet object? In other words, instead of:

var sine = new Sine(audiolet, 440)

do this:

var sine = new audiolet.Sine(440)

or even this:

var sine = audiolet.createSine(440)

This seems like the most obvious strategy to me, though perhaps I'm missing something.

@kn0ll
Copy link
Author

kn0ll commented Oct 25, 2012

i considered that route as well, but ultimately, it doesn't solve the inconvenience. this would still require anything creating nodes to have reference to that audiolet graph object, forcing you to pass it all over the place.

while on one hand i realize in a scenario with multiple graphs, this might be totally unavoidable... it might not be bad for audiolet to only assume 1 graph in any application. i realize this is also not ideal, but given the sink.js limitations, it does make some sense. (ie. if you can only have 1 master output, assuming 1 graph might not be inherently bad).

@mattdiamond
Copy link

@catshirt wouldn't creating nodes via audiolet object methods allow you to use/store that reference via this within the node constructor? Why would you still need to pass around an audiolet object?

Edit: I suppose your point is that you would still need the root audiolet object to call those methods on it. Yes, that's true. But I think anyone using this should be maintaining that object in an easily accessible place, and it just seems cleaner to call a method on it rather than pass it in as a parameter.

I don't think keeping around the root audiolet object is really an inconvenience... most javascript libaries require you to refer to either an instance of a library object, or to call static methods on a globally available library object. So whatever you do, you're probably going to need something that's globally accessible. The question is more how you use that object, rather than worrying about scope.

@kn0ll
Copy link
Author

kn0ll commented Oct 25, 2012

you're right- but there are many parts of my application which create nodes outside of the context of an audiolet object. what it really boils down to here is that audiolet.Sine(440) and Sine(audiolet, 440), for all intents and purposes, are no different. i'm hoping for a simpler Sine(440).

@mattdiamond
Copy link

@catshirt see my edit above... and yeah, in that case you would need to maintain some sort of singleton Audiolet graph object.

Edit: I also think it's better to force the user to rely on a single library object, rather than pollute the global scope with a whole bunch of new object constructors. Just my opinion though.

I would also note that this is how the Web Audio API does it... you create a single audio context, and then use that to generate all of your nodes via object methods.

@kn0ll
Copy link
Author

kn0ll commented Oct 25, 2012

a single graph would be the easiest solution. but i don't think it's the only one.

audiolet objects don't actually need the reference to the graph, as much as they need references to properties of that graph (ie. sampleRate), which could be obtained through other methods. for instance, audiolet could pass these parameters to the generate function during the recursive tick. a bit of work is involved here, and the generate() api would grow substantially, but it is a solution.

@oampo
Copy link
Owner

oampo commented Oct 26, 2012

How about using some sort of global namespace object, and getting rid of the Audiolet class all together? So something like:

var audiolet = {};

audiolet.Output= function() {
    audiolet.sampleRate = 44100;
};

audiolet.Sine = function(frequency) {
    print(frequency);
    print(audiolet.sampleRate);
};

output = new audiolet.Output();
sine = new audiolet.Sine(300);

If, like Nic, you just wanted each object as a global then we could maintain an optionally imported file which says:

var Output = audiolet.Output;
var Sine = audiolet.Sine;

I'm don't like the createWhateverNode style very much, because in Audiolet you can create custom nodes using the same syntax as it uses internally. So if you wanted to make a custom node you would also have to write a createWhateverNode function to keep a consistent API, which seems like an unnecessary step.

The obvious issue with the style I've suggested is that it doesn't allow multiple outputs running at different sample rates. That said, I don't see that happening in the Web Audio API any time soon, as I can see that it would present significant architectural challenges for not too much gain.

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

No branches or pull requests

3 participants