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

nanotunes

v0.4.1

Published

A small music format and an accompanying implementation using OscillatorNode

Downloads

16

Readme

NanoTunes

npm version

NanoTunes is a small schema for structuring music. This repository includes a JavaScript implementation, built upon OscillatorNode.

Developers must shape their own sounds; NanoTunes is simply a means of representing the notes that should be played, and for how long per bar.

Try out the demo.

The Schema

The general structure is:

<Instrument Name /><Note 1><Letter /><Octave /><Length /></Note 1>...<Note n><Letter /><Octave /><Length /></Note>

Where:

  • <Instrument Name> is a three-character string that refers to a previously defined instrument
  • <Note n> is a string composed of three ordered parts:
    • The note's musical letter (A-G), and an optional # to sharpen the note by a semitone. X0 can be used as a rest note
    • The octave (1-8)
    • The length of the note (1-16)

A "Note" On Note Lengths

As of this version, NanoTunes only supports semiquaver (1/16th) resolution (this will hopefully be increased in the next major release.) Essentially, this means:

  • A note length of 16 will last for a whole bar (semibreve)
  • A note length of 8 will last for half a bar (minim)
  • A note length of 4 will last for half a bar (crotchet)
  • A note length of 2 will last for half a bar (quaver)
  • A note length of 1 will last for half a bar (semiquaver)

Example

VOXC44A#412 translates to:

  • Play this track with a user-defined instrument called "VOX";
  • Play C4 for a quaver length;
  • Play A#4 for the remainder of the bar;

JavaScript Implementation

Example

'use strict';

var instruments = {
    VOX: {
        wave: 'square',
        pan: -0.5,
        gain: 0.3
    },

    BSS: {
        wave: 'triangle',
        pan: 0.5,
        gain: 0.7
    },

    GTR: {
        wave: 'sawtooth',
        pan: 0.8,
        gain: 0.4
    },
};

var tracks = {
    title: {
        bpm: 180,
        isLooping: true,

        parts: [
            'VOXC44C44G44A44A#44A44G44E44',
            'GTRC32C42C32C42E32E42E32E42G32G42G32G42C32C42C32C4',
            'BSSC24C24G14G14A#14A#14B14B14',
        ]
    }
};

var nanoTunes = new NT(instruments, tracks);

nanoTunes.play('title');

File Sizes:

  • Unminified - 4.3 KB
  • Minified - 1.6 KB
  • Minified and gzipped - 830 bytes

Browser Compatibility

  • Chrome
  • Firefox
  • Edge
  • Safari - works, but somewhat buggy

Setup

npm

Nanotunes is available as a CommonJS module, which is compatible with Browserify and Webpack.

npm i --save nanotunes

This module exposes the NT constructor directly:

'use strict';

const NT = require('nanotunes');
const nanoTunes = new NT(instruments, tracks);

Standalone

There are two scripts in the dist directory

  • An unminified version for those who minify everything
  • A minified version for those who bundle third-party dependencies separately

Loading this script will attach the NT constructor to the window object.

API

NT(instruments, tracks [, audioContext])

A constructor function to create a new instance of NanoTunes. The third parameter, which is optional, allows you to use a previously instantiated AudioContext. This is desirable if, for example, you're also generating sound effects with the Web Audio API.

Defining Instruments

The instruments parameter is an Object whose keys are three-letter instrument names. The below properties can be configured for each definition. most of which conform with the Web Audio API:

  • wave - the instrument's waveform. This can be any value assignable value to OscillatorNode.type. Unfortunately, custom waves aren't supported at this time, but will be available in the next major release

  • pan - controls the instrument's stereo panning. Like StereoPannerNode's pan property, it can range from -1 for the left speaker, to 1 for the right speaker

  • gain - controls the instrument's pre-output gain. Like GainNode's gain property, it can be a positive number

Defining Tracks

The tracks parameter is an Object whose keys are identifiable track names. For each, these properties can be specified:

  • bpm: - the song's beats per minute

  • isLooping - the song will loop infinitely if this is truthy, otherwise it will automatically stop after a single play

  • parts - an array of strings for each track. These will be played in parallel

NT.prototype.play(trackName)

Plays a track by name.

NT.prototype.stop()

Stops playing the current track.

The onStop callback

It's possible to attach a method to your NanoTunes instance called onStop. This will invoke whenever a non-looping track ends. This is useful for scheduling.

var nanoTunes = new NT(instruments, tracks);

nanoTunes.onStop = function onStop() {
    console.log('Current track has ended.');
};

Building Locally

run npm i in the project's directory, which will install Babel. This is used to transpile ES2015 block variables and arrow functions to their ES5 counterparts, because Closure Compiler doesn't support this latest standard as a compilation target. I therefore thought that it would beneficial to align the languages of both the unminified and minified versions. Once Closure supports ES2015 traspilation, Babel will be removed.

Additionally, the minified build is generated by Closure Compiler. You'll need to download the compiler JAR and expose it to your environment as closure-compiler. You can achieve this by writing a shell wrapper and placing this in one of your $PATH's directories.

Scripts

  • npm run build - builds both versions of the distributable, and copies the minified version to the demo directory

Tests

There are some unit tests which can be run with npm test. Increasing coverage is ongoing. Functional tests will also be available soon.