• Stars
    star
    382
  • Rank 112,241 (Top 3 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 4 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A super small music generator for use in size-limited JavaScript productions

ZzFX Music Generator

This is a music generator for use in tiny JavaScript productions (i.e. js13k games). ZzFXM uses a modified version of the super-tiny ZzFX library by Frank Force to generate instruments. The modified version of ZzFX is able create an array of audio data without immediately playing it.

The song format is loosely based on the MOD format, using patterns to handle repeating blocks of song data. Unlike MOD, patterns can be variable in length allowing repeatitive sequences of pattern data to be broken down into smaller chunks. Each pattern can also contain a variable number of channels, reducing the need to store empty data.

Use

<!-- load dependencies -->
<script src="zzfx.js"></script>
<script src="zzfxm.min.js"></script>

<script>
  // Create a song
  let mySongData = zzfxM(...song);

  // Play the song (returns a AudioBufferSourceNode)
  let myAudioNode = zzfxP(...mySongData);

  // Stop the song
  myAudioNode.stop();
</script>

Tooling

This repo contains various tools to help you generate and work with ZzFXM songs:

Tracker

A browser-based music tracker for composing songs for ZzFXM. (Available online.)

Song Conversion Tool

A CLI tool for converting file in ProTracker MOD (M.K.) format to the ZzFXM format. This allows you to use tools such as MilkyTracker or the browser-based Bassoon Tracker to author your songs. In order to keep ZzFXM small, only the volume and pattern break effects are 100% supported. The volume sliding effect is partially emulated by the song conversion tool by replacing the effect with computed volume steps.

Song Packer Tool

The song packer CLI tool compresses song data. It uses plugins so you can extend it with custom code if you need to.

Local Modules

This repo contains various local node modules that are shared between the tools. Please use them if you wish to create additional tooling.

Song Format

A ZzFXM song is a series of nested arrays containing instrument, pattern and sequence data:

[                                     // Song
  [                                     // Instruments
    [.9, 0, 143, , , .35, 3],             // Instrument 0
    [1, 0, 216, , , .45, 1, 4, , ,50],    // Instrument 1
    [.75, 0, 196, , .08, .18, 3]          // Instrument 2
  ],
  [                                     // Patterns
    [                                     // Pattern 0
      [                                     // Channel 0
        0,                                    // Using instrument 0
        -1,                                   // From the left speaker
        1,                                    // play C-1
        0, 0, 0,                              // rest (x3)
        3.5,                                  // play E-1 with 50% attenuation
        0, 0, 0                               // rest (x3)
      ],
      [                                     // Channel 1
        1,                                    // Using instrument 1
        1,                                    // From the right speaker
        2,                                    // play D-1
        2.25,                                 // play D-1 with 25% attenuation
        3.5,                                  // Play E-1 with 50% attenuation
        4.75,                                 // Play F-1 with 75% attenuation
        -1,                                   // Release the note
        0, 0, 0                               // rest (x3)
      ]
    ]
  ],
  [                                     // Sequence
    0,                                    // Play pattern 0
    0,                                    // ...and again
  ],
  120,                                  // 120 BPM
  {                                     // Metadata
    title: "My Song",                      // Name of the song
    author: "Keith Clark"                  // Name of the author/composer
  }
]

Song Structure

[
  <instrument-list>,
  <pattern-list>,
  <sequence>,
  <speed>?,
  <metadata>?
]

<instrument-list> structure

[
  <instrument>,
  ...
]

<instrument> structure

[
  <zzfx-sound-volume>?,
  <zzfx-sound-randomness>?,
  <zzfx-sound-frequency>?,
  <zzfx-sound-attack>?,
  <zzfx-sound-sustain>?,
  <zzfx-sound-release>?,
  <zzfx-sound-shape>?,
  <zzfx-sound-shapeCurve>?,
  <zzfx-sound-slide>?,
  <zzfx-sound-deltaSlide>?,
  <zzfx-sound-pitchJump>?,
  <zzfx-sound-pitchJumpTime>?,
  <zzfx-sound-repeatTime>?,
  <zzfx-sound-noise>?,
  <zzfx-sound-modulation>?,
  <zzfx-sound-bitCrush>?,
  <zzfx-sound-delay>?,
  <zzfx-sound-sustain-volume>?,
  <zzfx-sound-decay>?,
  <zzfx-sound-tremolo>?
]

An instrument is an array of optional ZzFX sound parameters. Any missing paramaters will be populated using the ZzFX default values.

Param Description Default Min Value Max Value
volume Volume scale (percent) 1 -1000000000 1000000000
randomness How much to randomize frequency (percent Hz) 0.05 -1000000000 1000000000
frequency Frequency of sound (Hz) 440 -1000000000 1000000000
attack Attack time, how fast sound starts (seconds) 0 0 3
sustain Sustain time, how long sound holds (seconds) 0 0 3
release Release time, how fast sound fades out (seconds) 0 0 3
shape Shape of the sound wave (0=sin, 1=triangle, 2=saw, 3=tan, 4=bit noise) 0 - -
shapeCurve Squarenes of wave (0=square, 1=normal, 2=pointy) 0 0 1000000000
slide How much to slide frequency (kHz/s) 0 -1000000000 1000000000
deltaSlide How much to change slide (kHz/s/s) 0 -1000000000 1000000000
pitchJump Frequency of pitch jump (Hz) 0 -1000000000 1000000000
pitchJumpTime Time of pitch jump (seconds) 0 -1000000000 1000000000
repeatTime Resets some parameters periodically (seconds) 0 -1000000000 1000000000
noise How much random noise to add (percent) 0 -1000000000 1000000000
modulation Frequency of modulation wave, negative flips phase (Hz) 0 -1000000000 1000000000
bitCrush Resamples at a lower frequency in (samples*100) 0 -1000000000 1000000000
delay Overlap with itself for reverb and flanger effects (seconds) 0 0 1000000000
sustainVolume Volume level for sustain (percent) 1 -1000000000 1000000000
decay Decay time, how long to reach sustain after attack 0 0 1
tremolo Trembling effect, rate controlled by repeat time (precent) 0 0 1

<pattern-list> structure

[
  <pattern>,
  ...
]

<pattern> structure

[
  <channel>,
  ...
]

<channel> structure

[
  <channel-instrument>, <channel-panning>, <channel-note>+
]

Channel data is a single array containing the instrument, panning and note data the current pattern. The first slot indicates which instrument to use for playing notes. Slot 2 contains the channel panning value and slots 3 onwards hold the note. If the array slot for an instrument, panning or note value is left empty it will coalesced to 0.

<channel-instrument> structure

<integer>

This contains an integer index pointing to the songs instrument array.

<channel-panning> structure

<number>

Set the stereo positioning of the song channel. A value of -1 will cause the channel to play from the left speaker. A value of 1 will cause the channel to play from the right speaker. A value between -1 and 1 will move the channel between the left and right speaker, with 0 causing the channel to play from both.

<channel-note> structure

<number>

The note value describes both the period and attenuation of a note. The period is the integer part of the number and the attentuation is the decimal part (0 - 0.99).

If the period is a value between 1 and 36 the corresponding note will be played using the channel instrument. When a new period is set any note currently playing in the channel is stopped and the channel attenuation is reset. A note value of 0 indicates a noop and -1 indicates note release (stops playing the note)

Value Note Value Note Value Note
01 C-1 0d C-2 19 C-3
02 C#1 0e C#2 1a C#3
03 D-1 0f D-2 1b D-3
04 D#1 10 D#2 1c D#3
05 E-1 11 E-2 1d E-3
06 F-1 12 F-2 1e F-3
07 F#1 13 F#2 1f F#3
08 G-1 14 G-2 20 G-3
09 G#1 15 G#2 21 G#3
0a A-1 16 A-2 22 A-3
0b A#1 17 A#2 23 A#3
0c B-1 18 B-2 24 B-3

The attenuation component is used to control volume - here is an example of playing consecutive C-1 notes while fading out:

[
  1,    // full volume
  1.2,  // 80% volume
  1.4,  // 60% volume
  1.6,  // 40% volume
  1.8   // 20% volume,
  -1    // release (mute the note)
]

<sequence> structure

[
  <integer>,
  ...
]

Sequence is an array of numbers indexing <pattern> entries in the <pattern-list>. Each pattern in the sequence is played until there are no remaining values, at which point the song is complete.

[0, 1, 1, 2]       // play pattern 0 followed by pattern 1 (twice) then pattern 2

<speed> structure

<integer>

The speed of the song in BPM.

<metadata> structure

{
  <song-property>,
  ...
}

Metadata is used to store song information that isn't required for playback such as the title, credits and human-readable aliases for data.

Property Description
title Title of the song
author Name of the composer
authorUrl URL of the composer (Website, GitHub profile, Twitter)
license The license for the song
instruments Array of instrument names that map to <instrument-list>
const mySong = [
  [
    [1, 0, 200],
    [1, 0, 500]
  ],
  [ /* ... patterns ... */ ],
  [ /* ... sequence ... */ ],
  120,
  {
    "title": "My Song",
    "author": "Keith Clark",
    "authorUrl": "https://keithclark.co.uk/"
    "license": "CC0",
    "instruments": ["Bass", "Piano"]
  }
]

More Repositories

1

selectivizr

selectivizr is a JavaScript utility that emulates CSS3 pseudo-classes and attribute selectors in Internet Explorer 6-8.
JavaScript
1,715
star
2

gadebugger

A Chrome, Firefox & Opera devtools extension for debugging Google Analytics tracking code
JavaScript
238
star
3

3d-model-element

A custom element for rendering inline 3D models in a HTML document and allowing them to be transformed with CSS.
JavaScript
204
star
4

css-feature-toggle-devtools-extension

A devtools extension for toggling CSS features allowing developers to see how pages/apps render in browsers that don't support modern CSS features
JavaScript
157
star
5

fuse-devtools

A boilerplate for creating a devtools extension for multiple browsers from a single code base.
JavaScript
134
star
6

JQuery-Extended-Selectors

Extends jQuery to add support for CSS3 xxx-of-type selectors
134
star
7

cssvr

CSSVR is an experiment that simulates browser support for creating VR experiences using media queries and CSS transforms.
JavaScript
82
star
8

ComputedStyleObserver

Prototype implementation of a `computedStyle` observer for DOM elements
JavaScript
19
star
9

surrogate

This is a tiny JavaScript library targeted at modern web browsers and designed to mimic the common parts of jQuery's funtions and syntax using modern ECMAScript and DOM implementations
JavaScript
4
star
10

imagedata

A collection of packages for working with images in JavaScript environments that don't implement the ImageData interface.
JavaScript
2
star
11

zzfxm-songs

A collection of songs for use with ZzFXM
2
star
12

sculpt

JavaScript
2
star
13

stylescribe

Stylescribe is a CSS documentation generator. It's goal is to produce a reference document that can be used to quickly build web pages without having to dive into the inner workings of a projects CSS.
JavaScript
2
star
14

atari-chunked-blits

Testing the feasibility of automatically breaking HOG blits into smaller chunks, allowing large objects to be drawn without interfering with interrupts
Assembly
2
star
15

selection-element

A web component for selecting HTML elements or other web components.
JavaScript
1
star