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

.chain method won't work after array mutation with .splice and .slice methods #1226

Open
ValentinSvidrigaylov opened this issue Feb 11, 2024 · 6 comments

Comments

@ValentinSvidrigaylov
Copy link

Describe the bug

When I connect an array of Tone.js effects to UserMedia (basically any audio source) and then use .splice and .slice methods on this array that move element of an array from one index to another, effects doesn't work anymore, and it just connects clean sound to the Destination node.

To Reproduce

let mic = new Tone.UserMedia();
let t = [new Tone.Distortion(1).toDestination(), new Tone.FeedbackDelay(0.6).toDestination()];
mic.disconnect().chain(...tt).toDestination();
function moved(array, from, to, on = 1) {
  return array = array.slice(), array.splice(to, 0, ...array.splice(from, on)), array
}
//this can be written as mic.disconnect().chain(...moved(t,0,1), Tone.Destination), but this way it just disconnects all nodes because .chain method doesn't work properly here.
mic.disconnect().chain(...moved(t,0,1)).toDestination();
    
Expected behavior

These effects are supposed to swap their positions, and the clean delay effect becomes distorted.

What I've tried

Though it doesn't work with splice and slice simultaneously, it works when these methods are used separately but not together on one array. Other methods like push and pop, however, work fine.

@Soviut
Copy link

Soviut commented Feb 19, 2024

I'm guessing but your moved function has some very weird syntax. You're making a copy of the array with slice but immediately overwriting it, trying to splice it, then return it all on one line? Is there a reason you're doing it that way?

It looks like you might be mixing up multiple solutions from this answer on StackOverflow https://stackoverflow.com/a/49874250/46914 since you're using the on = 1 arg they suggest.

However, you're missing the spread ... operator.

function move(arr, from, to, on = 1) {
  return arr.splice(to, 0, ...arr.splice(from, on))
}

That said, I think one of the prior solutions is simpler. Note the [0] to index the single item spliced in the "from" operation.

function move(arr, from, to) {
  return arr.splice(to, 0, arr.splice(from, 1)[0])
}

Either will work.

@ValentinSvidrigaylov
Copy link
Author

First of all, thank you for the answer.

I'm guessing but your moved function has some very weird syntax. You're making a copy of the array with slice but immediately overwriting it, trying to splice it, then return it all on one line? Is there a reason you're doing it that way?

Yes, it's just an example of code where the issue happens (and yes, I found it on StackOverflow).

It looks like you might be mixing up multiple solutions from this answer on StackOverflow https://stackoverflow.com/a/49874250/46914 since you're using the on = 1 arg they suggest.

However, you're missing the spread ... operator.

function move(arr, from, to, on = 1) {
  return arr.splice(to, 0, ...arr.splice(from, on))
}

In fact, in my code I have something like this:

Array.prototype.move = function(from, to) {
    this.splice(to, 0, this.splice(from, 1)[0]);
};

which also doesn't work.

That said, I think one of the prior solutions is simpler. Note the [0] to index the single item spliced in the "from" operation.

function move(arr, from, to) {
  return arr.splice(to, 0, arr.splice(from, 1)[0])
}

Either will work.

I've tried it out, and it doesn't seem in tonejs for some reason: positions of effects are changing, but they aren't able to be connected anymore:

function move(arr, from, to) {
  return arr.splice(to, 0, arr.splice(from, 1)[0])
}

Tone.context.lookAhead = 0;

let distortion = new Tone.Distortion(1)
let delay = new Tone.FeedbackDelay(0.6)

let effects = [distortion, delay]

let mic = new Tone.UserMedia()
mic.open()

mic.disconnect().chain(...effects,Tone.Destination)
move(effects,0,1)
mic.disconnect().chain(...effects,Tone.Destination)

Again, thanks for the answer. I hope there is some solution to this issue.

@Soviut
Copy link

Soviut commented Feb 19, 2024

One thing I noticed is you're trying to add Tone.Destination to the chain. But the docs say

Add a master effects chain. NOTE: this will disconnect any nodes which were previously chained in the master effects chain.

Based on their example it should be

Tone.Destination.chain(...effects);

Note that you don't need to use disconnect() since chain() already does that, according to the docs.

@ValentinSvidrigaylov
Copy link
Author

ValentinSvidrigaylov commented Feb 19, 2024

One thing I noticed is you're trying to add Tone.Destination to the chain. But the docs say

Add a master effects chain. NOTE: this will disconnect any nodes which were previously chained in the master effects chain.

Based on their example it should be

Tone.Destination.chain(...effects);

Note that you don't need to use disconnect() since chain() already does that, according to the docs.

Yeah, Tone.Destionation is in chain method only to make it inline more simple. The problem is that I've tried out examples from docs you've provided, but this still doesn't work for some reason. Here are the changes made:

Tone.Destination.chain(...effects);
mic.toDestination();
move(effects,0,1);
Tone.Destination.chain(...effects);
mic.toDestination();

From what I've tried, the problem occurs when the .chain method is called and not when the array mutates itself. Thank you for your reply yet again.

@Soviut
Copy link

Soviut commented Feb 20, 2024

Yeah, I gave it a try myself and it seems that only the first chain call is honoured.

@ValentinSvidrigaylov
Copy link
Author

I found out one more thing:
This issue also happens when disposing all effects and then connecting:

effects.map(e=>e.dispose())
mic.disconnect().chain(...effects,Tone.Destination)

So I guess I'm just misunderstanding something and doing something wrong.

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