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

m8-js

v0.2.1

Published

Library for loading and interacting with Dirtywave M8 instrument/song files.

Downloads

3

Readme

m8-js

This repository contains a JavaScript library for parsing Dirtywave M8 files, as well as a CLI for interacting with M8 files. The hopes are not to provide yet another UI for M8 files, or to create any sort of competing product, but to provide programmatic access to the M8 resources stored in the M8 files for things like third-party features (things that maybe M8 doesn't support itself, but you find useful) and utilities.

Current Status

As of version v0.1.0, m8-js has the ability to read and write all known M8 file types. The API and its object model are pretty solid, complete with unit test over 99% code coverage. The CLI is equally solid, also unit tested with over 99% code coverage.

Installation

Global

Installation is performed by issuing the following command:

npm install m8-js --global

Once you do this, m8 should be available.

CLI Usage

m8 --help or m8 help should give you enough of a starting point for now. Just know that all commands support the --help flag for command-specific help.

In 0.2.1, the m8 command itself is now equivalent to the newly added view command which will let you print an M8 file without specifying the M8 file type. (For example, if you have an M8 song file, you can run m8 PATH instead of m8 song view PATH.)

API

m8-js provides an API for both reading/writing M8 files, but it also provides an object model for programmatically creating and updating M8 files. Below are some examples to help expedite your m8-js usage.

Note: For an API Reference, please refer to docs/API.md.

API Basics

The objects in m8-js were modeled based on my own interpretation of the raw M8 file data as represented in the M8 UI. EVERY object in m8-js will mirror M8's unaltered equivalent when created. For example, if you create a new Song object, its representation is identical to a newly created Song in M8. The same goes for Instrument types, all settings, etc. If you programmatically create anything, just know that if its constructor takes values, the default values mirror the M8 default values.

Object/JSON Representation

Every type in lib/types has an asObject instance method that will return a JavaScript Object representation of itself. Also, every type in lib/types has a static fromObject that will allow you to create an instance of itself based on the JavaScript Object provided.

Reading an M8 file

M8 files are binary files are binary in format, and m8-js provides an API for reading all supported M8 files (Instruments, Scales, Songs and Themes). Here is an exmaple that hows how to read a file from disk:

const fs = require('fs')
const M8 = require('..')

const m8File = M8.loadM8File(Uint8Array.from(fs.readFileSync(m8FilePath))

At this point, m8File will either be a lib/types/Scale, lib/types/Song, lib/types/Theme or one of the instrument types in lib/types/instruments/.

Writing an M8 file

Here is an exmaple that hows how to write an M8 type to disk:

const fs = require('fs')
const M8 = require('..')

fs.writeFileSync(M8.dumpM8File(m8File))

So long as m8File is either a lib/types/Scale, lib/types/Song, lib/types/Theme or one of the instrument types in lib/types/instruments/, M8.dumpM8File will return a Uint8Array corresponding to the raw bytes for the M8 file.

Caveats

While the m8-js API allows for programmatically creating M8 types, and writing them to files, there is data in the M8 files that are unknown. While creating M8 file types complete via the API should work without issue, the safest way to ensure complete binary accuracy, use M8.loadM8File to load the type you want and after you've manipulated it programmatically, use M8.writeM8File to write it back. If you do not use M8.loadM8File, the unknown bytes are written using known default values for the regions in question instead of the original values loaded from disk.

Development/Local

Or you can use a local development installation by cloning this repository and installing its dependencies via npm install.

Once you do this, ./bin/m8 should be available.

Thanks

When I initially started this effort, the only resource I could find to start this journey was this: https://gist.github.com/ftsf/223b0fc761339b3c23dda7dd891514d9 Using this, a hex editor and some time on the Dirtywave M8 Discord, this project came to life. Thanks @impbox!