changing Tone.js sequencer events dynamically

48 Views Asked by At

I want to change the Sequencer Object's events array while it is playing. The following code is from Tone.js Sequencer Page.

const synth = new Tone.Synth().toDestination()
const seq = new Tone.Sequence((time, note) => {
    synth.triggerAttackRelease(note, .1, time)
}, ["C4", ["E4", "D4", "E4"], "G4", ["A4", "G4"]] /*I wanna change this arr*/).start(0)

I am a bit lost, to be honest. In the seq Object, there is a property called

Tone.Sequencer._events

And underneath the _events there are handlers that called get and set, but when I checked the source

private _createSequence(array: any[]): any[] {
        return new Proxy(array, {
            get: (target: any[], property: PropertyKey): any => {
                // property is index in this case
                return target[property];
            },
            set: (target: any[], property: PropertyKey, value: any): boolean => {
                if (isString(property) && isFinite(parseInt(property, 10))) {
                    if (isArray(value)) {
                        target[property] = this._createSequence(value);
                    } else {
                        target[property] = value;
                    }
                } else {
                    target[property] = value;
                }
                this._eventsUpdated();
                // return true to accept the changes
                return true;
            },
        });
    }

And I decided, I could use a little help at this point. Is there any way to change/replace the array that is playing without stopping the Tone.Transport?

1

There are 1 best solutions below

1
merkwur On

I have found a solution to this issue: I am not equipped to give any extra information about the Proxy Arrays in JavaScript, but here is a simple start.

const synth = new Tone.Synth().toDestination()
const seq = new Tone.Sequence((time, note) => {
    synth.triggerAttackRelease(note, .1, time)
}, ["C4", ["E4", "D4", "E4"], "G4", ["A4", "G4"]] /*I wanna change this arr*/).start(0)

const eventArray = seq._events // this points to seq._eventsArray

eventArray.push("D4") // allowing array operations
eventArray[n] = ["F3", "G#3"]
eventArray.splice(0, n) // etc...

seq._eventsUpdated() // forces to update the array

However, note that this solution did not satisfy my requirements, the changes do not affect the array immediately but happen sometime after. The technical side is beyond my knowledge to explain or use exact jargon that is related to the issue. sorry about this. But as another solution, I have created my sequencer with using basic javascript setInterval and setTimeout methods.