interchange-file-format v0.4.1
interchange-file-format
A module for working with Interchange File Format (IFF) data.
Installation
$ npm install interchange-file-formatExample
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 chunkchunk = 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 diskgroup.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