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

interchange-file-format

v0.4.1

Published

Interchange File Format (IFF) codec.

Downloads

27

Readme

interchange-file-format

A module for working with Interchange File Format (IFF) data.

Installation

$ npm install interchange-file-format

Example

The following example implements a few structures for the AIFF (Audio Interchange File Format)

const { Form, Chunk, extensions } = require('interchange-file-format')
const fs = require('fs'

extensions.set('COMM', class CommonChunk extends Chunk {
  get numChannels() { return this.readUIntBE(0, 2) }
  get numSampleFrames() { return this.readUIntBE(2, 4) }
  get sampleSize() { return this.readUIntBE(6, 2) }
  get sampleRate() {
    const x = this.readUIntBE(8, 2)
    const y = this.readUIntBE(10, 1)
    const z = this.readUIntBE(11, 1)
    const pre = 16398
    const pad = x - pre
    const shifted = (y << 8) + z
    return shifted << pad
  }
})

extensions.set('SSND', class SoundDataChunk extends Chunk {
  get offset() { return this.readUIntBE(0, 4) }
  get blockSize() { return this.readUIntBE(4, 4) }
  get soundData() { return this.slice(8) }
})

const stream = fs.createReadStream('/path/to/audio/track.aif')
const form = new Form({ type: 'AIFF' })

stream.pipe(form.createWriteStream()).on('finish', () => {
  for (const chunk of form) {
    // `chunk` could be `CommonChunk` or `SoundDataChunk` when `COMM`
    // and `SSND` chunk IDs are foud
    console.log(chunk)
  }
})

API

ID

The ID class represents a container for 32 bits of characters, the concatenation of four printable ASCII character in the range ' ' (SP, 0x20) through '~' (0x7E). Spaces (0x20) cannot precede printing characters; trailing spaces are allowed. Control characters are forbidden.

The ID class extends Uint8Array and is polymorphic with the Buffer API.

id = ID.from(bufferOrString)

Creates a 4 byte ID instance from a Buffer or string. A Chunk can be identified by an ID. A Form will use an ID to describe its type.

const id = ID.from('FORM')
validated = id.set(bytes)

Set id value bytes on ID instance.

if (!id.set(bytesOrString)) {
  // bytes invalid or too large
}
buffer = id.toBuffer()

Convert ID instance directly to Buffer, using the same internal ArrayBuffer for this instance.

const buffer = id.toBuffer()

Chunk

The Chunk class is a container for bytes with a known ID and size. A Chunk can be manually constructed or derived from an existing buffer (see Chunk.from()).

chunk = new Chunk(id, options)

Create a new Chunk instance from ID with options where options can be:

{
  size: required, // size in bytes of chunk body
  ancestor: null  // the ancestor this chunk is derived from
}
const chunk = new Chunk('FORM', { size: 32 }) // 32 byte chunk body
chunk.set(bytes) // set bytes on chunk

chunk = Chunk.from(buffer, options)

Create a new Chunk from a given buffer with constructor options.

const chunk = Chunk.from(bufferFromSource)
chunk.data

A Buffer pointer to the Chunk data.

chunk.set(bytes[, offset])

Set bytes or a string on Chunk.

chunk = chunk.map(map)

Map over the chunks in this chunk returning a new Chunk instance.

chunk = chunk.filter(filter)

Filter over the chunks in this chunk returning a new Chunk instance.

chunk = chunk.slice(start[, stop])

Creates a new Chunk instance as a slice from this instance.

array = chunk.toArray()

Convert Chunk into an Array.

buffer = chunk.toBuffer()

Converts (serializes) the Chunk to a Buffer, including the ID and size bytes as header values.

ChunkIterator

A Chunk iterator that implements the Iterator Protocol and satisfies the Iterable interface requirements.

iterator = ChunkIterator.from(buffer[, offset])

Creates a new ChunkIterator from a given buffer starting at an optional offset.

const iterator = ChunkIterator.from(bufferSource)
for (const chunk of iterator) {
  console.log('%s', chunk.id, chunk)
}

Group

An abstract class that extends Array that behaves like a container that for many things. Classes like Form and List extend this type for the FORM and LIST chunk types, respectively.

group = new Group(id, options)

Creates a new Group from a given ID with options where option can be:

{
  type: required, // A string type name for the group, this could be the
                  // FORM type, or the record type for a LIST
}
const form = new Group('FORM', { type: 'TEST' })

group = Group.from(buffer)

Creates a new Group instance from a given buffer, loading types and extensions based on parsed chunk IDs.

const form = Group.from(bufferSource) // `bufferSource` could be a AIFF file on disk
group.chunks

A concatenated buffer of all chunks in this group.

group.append(chunks)

Append a chunk or an array of chunks to the group, setting this instance as the chunks ancestor.

group.push(...chunks)

Pushes a new Chunk into the group, setting this instance as the chunks ancestor.

group.unshift(...chunks)

"Unshifts" or left pushes a new Chunk into the group, setting this instance as the chunks ancestor.

chunk = group.shift()

Shift a chunk out of the group, removing a reference to this instance as the ancestor.

chunk = group.pop()

Pop a chunk out of the group, removing a reference to this instance as the ancestor.

group = group.concat(...chunks)

Concatenates and returns a new Group instance with given chunks (or Group).

group = group.map(map)

Map over the chunks in this group returning a new Group instance.

group = group.filter(filter)

Filter over the chunks in this group returning a new Group instance.

group = group.slice(start[, stop])

Creates a new Group instance as a slice from this instance.

array = group.toArray()

Convert this instance into an Array.

buffer = group.toBuffer()

Creates a buffer from this Group instance flattening all chunks in the hierarchy.

stream = group.createReadStream()

Get a ReadStream for chunks in a Group instance.

stream = group.createWriteStream()

Get a WriteStream for writing chunks in a Group instance.

Form

A Group type with an ID set to FORM.

List

A Group type with an ID set to LIST.

CAT

A special Group type with an ID set to LIST with a restriction on the types of descendants being only other Group types.

extensions

A static Map of Group extensions that map a 4 byte chunk ID string to a class that extends Group or Chunk to handle extensions to the EA IFF 85 spec, such as AIFF (or AIFC) with the NAME or SSND types.

const { Chunk, Group, extensions } = require('interchange-file-format')
class TextChunk extends Chunk {
  get text() {
    return this.slice(0, this.size).toString()
  }
}

// when then `NAME` or `AUTH` chunk ID is seen in a `Group`, this class will be used
extensions.set('NAME', TextChunk)
extensions.set('AUTH', TextChunk)

License

MIT