Most roadmap tasks should be available here: https://github.com/beefchimi/earwurm/issues
While we are intentionally keeping the scope of Earwurm to an absolute minimum, there are still some features / tasks that remain to be completed.
- Should we make
contextavailable to the consumer so that they can re-use it for other things?- Can cause many complications within
Earwurm.
- Can cause many complications within
- Should we have some “SSR/node detection” to know if we can actually use the
Web Audio API?- Can the
Web Audio APIwork on a server / in node?
- Can the
- Should we offer a utility to help detect:
AudioContextsupport.webmformat support.opuscodec support.
- Should we implement the “distortion fix” within the
unlockmethod?Howleruses this, but I'm not sure if its relevant for evergreen browsers.
- Consider a
autoSuspendDelayconfig option.- Accepts a
msvalue that defaults to30000. - If
0is passed toautoSuspendDelay, then we consider that a “opt-out” value and disable the auto-suspension.
- Accepts a
- Should we allow “restarting” a
Earwurminstance after.teardown()has been called?- My current preference is, once
.teardown()is called, you are done with that instance and will not be resurrecting it. - We are not however setting
#contextandmanagerGaintonull, because that would introduce anulltype that I do not want to check for within the code.
- My current preference is, once
- Investigate if it makes any sense to utilize a
OfflineAudioContext. - Consider a
delayproperty for aSound.- The idea is that the
delayis persistent for that sound. - The
delayis included in each subsequentloop, instead of ONLY applying to the first iteration. - Maybe a
startPadandendPadmake sense?
- The idea is that the
- Should we offer a way to "pre-fetch" all audio data within an
Earwurm?- Otherwise, we will sometimes have a "delay" before audio begins playing for the first time.
- It would also be nice if a
Stackhad acachedboolean getter.
- Is it reasonable to cache the decoded
AudioBufferby storing it on theStackinstance?- We could introduce this private property:
#audioBuffer: AudioBuffer | null; - And then add an option to the
configforcacheAudioBuffer?: boolean; - This would have to be flagged as potentially "dangerous", as I imagine caching too many buffers creates considerable overhead.
- We could introduce this private property:
- Do we need to re-check the
#queuestate when a sound hasended?- This would be done within
Stack > #handleSoundEnded. - A sound goes into a
stoppingstate first, which will trigger#setStateFromQueue. There shouldn't be any reason for theendedevent to fail… but if so, then we will need to re-check.
- This would be done within
- Find out if
statechangeevent listeners automatically get removed upon calling.close()/ state change toclosedon aAudioContext.- If so, then I can remove the
.close().then()chain.
- If so, then I can remove the
- Consider adding a
readonly parentto bothStackandSound.- The value of each would be
thisfrom either theManageror theStack. - Example: This would allow me to know what
Stackmanages a particularSound.
- The value of each would be
- Consider setting
Stack > statetoclosedonteardown.- This way, there is a better mechanism to removing a
Stackafter listening to astatechange.
- This way, there is a better mechanism to removing a
Maybe there is some value in passing an array of GainNode/AudioNode for destination? If so, that might look something like:
export type AudioOutputs = [...GainNode[], AudioNode];
constructor(readonly outputs: AudioOutputs);
let lastConnection: GainNode | AudioNode = this.#gainNode;
outputs.forEach((node) => {
lastConnection = lastConnection.connect(node);
});