Research
Security News
Threat Actor Exposes Playbook for Exploiting npm to Build Blockchain-Powered Botnets
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.
audiolooper
Advanced tools
An audiolooper let's you loop your audiotracks in a very simple and intuitive way. The looping algorithm keeps the tracks automatically in sync.
This package is a part of the sountility collection!
The audiolooper tries to loope the tracks you add in a synced manner. It simply loops the tracks according to the first track you added to the looper. This makes looping easier in most cases (not always, don't expect any miracles). It was a long way until I arrived here. Before I created this package, I tried many different things in order to get a consistent looping (initially, I was using webworkers with setTimeout, but this led to very inconsistent timing and glichtes). This solution is very solid and offers consistent looping by using the webaudio BufferSourceNode objects.
Here I try to explain you, how audiolooper loops your tracks in a synced manner.
When the first track is added, it is looped over as is. All the following tracks will be synced with the first track you added. The looping algorithm makes the duration of the track you added after the first one a multiple of the first tracks duration. It will always be rounded up until it is a multiple of the first tracks duration.
:arrow_forward: The duration of the track you added becomes 1s. The track will be looped over now every 1s.
:arrow_forward: The duration of the track you added becomes 2s. The track will be looped over now every 2s.
:arrow_forward: The duration of the track you added becomes 10s. The track will be looped over now every 10s.
:arrow_forward: The duration of the track you added becomes 5s. The track will be looped over now every 5s.
I hope I was able to clarify how the audiolooper works! If you still have probblems understanding how it works, feel free to open an issue!
new AudioLooper(audioCtx)
To create a new audiolooper instance, you have to pass on parameter to the constructor: A valid AudioContext object.
.addTrack({ id, audioBuffer, trackAdded })
To add a track to the looper, use this method. The method expects one parameter, which has to be an object of the following structure:
{
id: ANY,
audioBuffer: BufferSourceNode,
trackAdded: Function
}
id: The id can be anything, but you'll need it refer to the tracks for later. I recommend using a library like uuid to generate ids.
audioBuffer: This needs to be a webaudio BufferSourceNode. This one will then be added to the looper and will be looped over.
trackAdded: This field must be a function. It is a callback function which will be executed when the track was added to the looper. This function can accept one parameter, which will be the final BufferSourceNode used by the looper (ATTENTION! The BufferSourceNode actually used by the looper is a different one, not the one you passed into the function).
.removeTrack({ id })
To remove a track, simply use this function. It requires an object ad its only parameter which has a field id, the id of the track you want to delete (you specified the id before, when you added the track).
ATTENTION! Removing the first track will lead to unexpected behaviour and will be disabled in the near future!
.pauseTrack({ id })
To pause a track, simply use this method. It requires an object as its only parameter which has a field id, the id of the track. (you specified the id before, when you added the track).
.playTrack({ id })
To play a track you paused before, simply use this method. It requires an object as its only parameter which has a field id, the id of the track. (you specified the id before, when you added the track).
.getCurrentTime({ id })
To get the time(seconds) which passed since the track was added, use this method. It requires an object as its only parameter which has a field id, the id of the track. (you specified the id before, when you added the track).
.exists({ id })
To check if a specific track was already added to the audiolooper, use this method. It requires an object as its only parameter which has a field id, the id of the track. (you specified the id before, when you added the track).
This is a small example which shows how to create a very simple loopstation.
import Recordy from 'recordy';
import AudioLooper from 'audiolooper';
const audioCtx = new AudioContext();
const recordy = new Recordy(audioCtx);
recordy.getInput()
.then((hasInput) => {
if (hasInput)
console.log(`Got mic input!`);
else
console.error(`Could not get mic input.`);
});
function render() {
const looper = new AudioLooper(audioCtx);
const mainDiv = document.createElement(`div`);
mainDiv.class = `main`;
const recordBtn = document.createElement(`button`);
const stopRecordBtn = document.createElement(`button`);
recordBtn.textContent = `Start recording`;
stopRecordBtn.textContent = `Stop recording`;
recordBtn.addEventListener(`click`, () => {
recordy.startRecording();
});
stopRecordBtn.addEventListener(`click`, () => {
recordy.stopRecording() // TRUE == Create audio object, FALSE = return blob
.then((blob) => {
// create arraybuffer from blob
const fileReader = new FileReader();
fileReader.addEventListener(`loadend`, () => {
audioCtx.decodeAudioData(fileReader.result)
.then((audioBuffer) => {
const id = Math.random() * 1000;
looper.addTrack({
id,
audioBuffer,
trackAdded: (bufferNode) => {
bufferNode.connect(audioCtx.destination);
}
});
});
});
fileReader.readAsArrayBuffer(blob);
});
});
mainDiv.appendChild(recordBtn);
mainDiv.appendChild(stopRecordBtn);
document.querySelector(`body`).appendChild(mainDiv);
}
render(recordy, audioCtx);
FAQs
AudioLooper - Loop your tracks with automatic synchronization.
We found that audiolooper demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.
Security News
NVD’s backlog surpasses 20,000 CVEs as analysis slows and NIST announces new system updates to address ongoing delays.
Security News
Research
A malicious npm package disguised as a WhatsApp client is exploiting authentication flows with a remote kill switch to exfiltrate data and destroy files.