npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

mercury-engine

v1.2.2

Published

The mercury engine generates web audio output from mercury code input

Downloads

46

Readme

⚠️ WORK IN PROGRESS, EXPERIMENTAL USE ONLY ⚠️

🌕 Mercury Engine

The engine (core) of the Mercury Live Coding Environment for the browser

This Package does not include the browser editor and user interface. This package allows you to include the Mercury webaudio engine into your own web projects and generate sound from the Mercury code. This engine is used in the Mercury-Playground, a browser based version of the environment.

Mercury currently has 2 versions:

🚀 Start Sketching Online! (recommended for beginners)

🚀 Install

Install in node_modules

$ npm install mercury-engine
const { Mercury } = require('mercury-engine');

const Engine = new Mercury();

Include in html

Include latest or a specific version of distribution (minified, es5) through url in script index.html

Recommended for most cases:

<script src="https://unpkg.com/mercury-engine/dist/mercury.min.es5.js"></script>

Other options:

<script src="https://unpkg.com/mercury-engine/dist/mercury.js"></script>
<script src="https://unpkg.com/[email protected]/dist/mercury.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/mercury.min.es5.js"></script>

Load the engine in the <script> code like so:

const { Mercury } = MercuryEngine;

const Engine = new Mercury();

Examples

See the examples folder for a few .html files that demonstrate the usage. Run them locally by cloning this repository with git clone https://github.com/tmhglnd/mercury-engine. Then cd mercury-engine and run a simple http-server, for example with the http-server node package (install globally with npm i -g http-server). Navigate to localhost:8080/examples and try them out.

Usage

Include and initialize

Include the package

const { Mercury } = require('mercury-engine');

Initialize the engine and include a callback function through { onload: }, this will be executed when samples are loaded.

const Engine = Mercury({
	onload: () => {
		console.log('This callback is called when samples are loaded!');
		console.log('The loaded samples:', Engine.getBuffers());
	}
});

Resume, evaluate and silence

Resume the transport and start the webaudio. This has to be done from a user interaction (click or keypress) to allow sound to play from the browser window.

Engine.resume();

Evaluate a mercury code file by providing a string of code. This also resumes the transport if .resume() was not called yet.

Engine.code(`
	set tempo 100
	new sample kick_909 time(1/4)
	new sample hat_909 time(1/4 1/8) gain(0.6)
	new synth saw note(0 0) time(1/16) shape(1 80)
`);

Stop the transport and silence the audio

Engine.silence();

Return the last succesfully evaluated code. If code is evaluated that resulted in an error it is not stored.

Engine.getCode();

Samples

Add your own samples from for example a url like raw github or freesound. The url can also contain a .json file that references multiple samples and the sample name.

Engine.addBuffers(files, callback);

For example use a json file containing sample names and urls

Engine.addBuffers('https://raw.githubusercontent.com/tmhglnd/mercury-engine/main/examples/samples/freesound-samples.json');

Or load samples directly by creating an array of urls

let s1 = 'https://cdn.freesound.org/previews/671/671221_3797507-lq.mp3';
let s2 = 'https://cdn.freesound.org/previews/145/145778_2101444-lq.mp3';

Engine.addBuffers([s1, s2]);

Add a callback function, this is called when all samples are loaded

Engine.addBuffers('https://someurl.json', () => {
	console.log('This callback is called when samples are loaded!');
	console.log('The loaded samples:', Engine.getBuffers());
});

Get the content of all the loaded Buffers, this is returned as a ToneAudioBuffers class

Engine.getBuffers();

Recording

Start the recording of the sound

Engine.record(true);

Returns 'started' if the recording is on

Engine.isRecording();

Stop the recording and download the file myRecording.webm

Engine.record(false, 'myRecording');

Meter

You can add a meter to the main audio output and poll for the amplitude value from the meter to for example create audio-reactive visuals in other programming languages such as Hydra or P5.js.

First add the meter, optionally with a smoothing factor (default=0.7)

Engine.addMeter();

Get the meter value as floating-point between 0-1

Engine.getMeter();

Store the meters amplitude value in a global variable for usage in other places and update regularly with a setInterval at a defined interval in milliseconds.

let amp;

setInterval(() => amp = Engine.getMeter(), 100);

For example control some visual parameter in Hydra

osc(10, 0.2, () => amp * 20).out();

MIDI

WebMIDI is included and started if the browser is compatible with it. If not, an error will be printed to the console. You can provide a callback function onmidi to execute some code when the WebMIDI enabling was succesful.

const Engine = Mercury({
	onmidi: () => {
		console.log('The WebMIDI status is:', Engine.midi.status);
		console.log('With inputs:', Engine.midi.inputs);
		console.log('And outputs:', Engine.midi.outputs);
	}
});

Settings

Set the BPM without using set tempo in the Mercury code

Engine.setBPM(140);

Set a randomized BPM

Engine.randomBPM();

Set the volume without using set volume in the Mercury code. Volume in floating amplitude 0 to 1.

Engine.setVolume(0.5);

Set the crossFade between 2 code evaluations without using set crossFade in the Mercury code. Time in milliseconds.

Engine.setCrossFade(500);

Set the HighPass Filter cutoff frequency without using set highPass in the Mercury code.

Engine.setHighPass(400);

Set the LowPass Filter cutoff frequency without using set lowPass in the Mercury code.

Engine.setLowPass(5000);

Get the value for any of the settings

console.log(Engine.bpm);
console.log(Engine.volume);
console.log(Engine.crossFade);
console.log(Engine.highPass);
console.log(Engine.lowPass);

Log function listener

Logs that are important for the Mercury coder are also emitted as a custom event in the browser. You can create an event listener for mercuryLog. The e.detail contains the printed message. This can be used to for example print things to custom html elements instead of the javascript console.

window.addEventListener('mercuryLog', (e) => {
	let p = JSON.stringify(e.detail).replace(/\,/g, ' ').replace(/\"/g, '');
	document.getElementById('logger').innerHTML += `${p}<br>`;
	console.log('customprint:', e.detail);
});

DOM elements from P5js

It is possible to control parameters from instruments in the Mercury code by writing a string that contains {} with the js code inside to get the dom value. For example when using DOM elements from the P5js library, such as sliders, they can be used in the code.

let slider;

// p5js setup function
function setup() {
	noCanvas();
	// create a slider with range 50 - 5000, initial 1000
	slider = createSlider(50, 5000, 1000, 0);
}

// use the slider value as a cutoff frequency for the filter
Engine.code(`new synth saw note(0 0) fx(filter low '{slider.value()}' 0.4)`);

📋 To Do

  • [ ] Include OSC communcation options via socket.io
  • [ ] Use engine in the Mercury-playground instead of the other code-base

🔋 Powered By

📄 Licenses

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.