Wavefile
Create, read and write wav files according to the specs. :star: :notes: :heart:
Install / Use
/learn @rochars/WavefileREADME
wavefile
Copyright (c) 2017-2019 Rafael da Silva Rocha.
https://github.com/rochars/wavefile
wavefile
Create, read and write wav files according to the specs.
- MIT licensed
- Use it in the browser (IE10+)
- Use it in Node.js
- Use it as a command line tool
- Handle files up to 2GB
- Zero dependencies
With wavefile you can:
- Create wav files
- Read wav files
- Change the bit depth of the audio
- Change the sample rate of the audio
- Read and write RIFF tags
- Set and delete cue points and their labels
- Create regions in wav files
- Encode/decode files as ADPCM, A-Law and μ-Law
- Turn RIFF files to RIFX and RIFX to RIFF
- Create or edit BWF metadata ("bext" chunk)
And more.
Install
npm install wavefile
To use it from the command line, install it globally:
npm install wavefile -g
Use
Node
const wavefile = require('wavefile');
let wav = new wavefile.WaveFile();
or
const WaveFile = require('wavefile').WaveFile;
let wav = new WaveFile();
or
import { WaveFile } from 'wavefile';
let wav = new WaveFile();
Browser
Use the wavefile.js file in the dist folder:
<script src="wavefile.js"></script>
<script>
var wav = new wavefile.WaveFile();
</script>
Or load it from the jsDelivr CDN:
<script src="https://cdn.jsdelivr.net/npm/wavefile"></script>
Or load it from unpkg:
<script src="https://unpkg.com/wavefile"></script>
Browser compatibility
IE10+. Should work in all modern browsers.
Cross-browser tests powered by
<a href="https://www.browserstack.com"><img src="https://rochars.github.io/wavefile/docs/Browserstack-logo@2x.png" width="150px"/></a>
Command line use
To see the available options:
wavefile --help
Node.js Example
const WaveFile = require('wavefile').WaveFile;
// Load a wav file buffer as a WaveFile object
let wav = new WaveFile(buffer);
// Check some of the file properties
console.log(wav.container);
console.log(wav.chunkSize);
console.log(wav.fmt.chunkId);
// Call toBuffer() to get the bytes of the file.
// You can write the output straight to disk:
let wavBuffer = wav.toBuffer();
// Call toDataURI() to get the file as a DataURI:
let wavDataURI = wav.toDataURI();
Table of Contents
Operation Manual
Create wave files from scratch
Use the fromScratch(numChannels, sampleRate, bitDepth, samples) method.
Mono:
let wav = new WaveFile();
// Create a mono wave file, 44.1 kHz, 32-bit and 4 samples
wav.fromScratch(1, 44100, '32', [0, -2147483, 2147483, 4]);
fs.writeFileSync(path, wav.toBuffer());
Stereo:
Samples can be informed interleaved or de-interleaved. If they are de-interleaved, WaveFile will interleave them. In this example they are de-interleaved.
// Stereo, 48 kHz, 8-bit, de-interleaved samples
// WaveFile interleave the samples automatically
wav.fromScratch(2, 48000, '8', [
[0, 2, 4, 3],
[0, 1, 4, 3]
]);
fs.writeFileSync(path, wav.toBuffer());
Possible values for the bit depth are:
"4" - 4-bit IMA-ADPCM
"8" - 8-bit
"8a" - 8-bit A-Law
"8m" - 8-bit mu-Law
"16" - 16-bit
"24" - 24-bit
"32" - 32-bit
"32f" - 32-bit floating point
"64" - 64-bit floating point
You can also use any bit depth between "8" and "53", like "11", "12", "17", "20" and so on.
A word on bit depth
Resolutions other than 4-bit, 8-bit, 16-bit, 24-bit, 32-bit (integer), 32-bit (fp) and 64-bit (fp) are implemented as WAVE_FORMAT_EXTENSIBLE and may not be supported by some players.
Read wave files
const WaveFile = require('wavefile').WaveFile;
wav = new WaveFile();
// Read a wav file from a buffer
wav.fromBuffer(buffer);
// Read a wav file from a base64 string
wav.fromBase64(base64);
// Read a wav file from a data URI
wav.fromDataURI(dataURI);
Add RIFF tags to files
You can create (or overwrite) tags on files with the WaveFile.setTag() method.
// Write the ICMT tag with some comments to the file
wav.setTag("ICMT", "some comments");
To get the value of a tag (if it exists), use WaveFile.getTag():
console.log(wav.getTag("ICMT"));
// some comments
You can delete a tag with WaveFile.deleteTag():
wav.deleteTag("ICMT");
Add cue points to files
You can create cue points using the WaveFile.setCuePoint() method. The method takes a object with the cue point data and creates a cue point in the corresponding position of the file. The only required attribute of the object is position, a number representing the position of the point in milliseconds:
// to create a cue point
wav.setCuePoint({position: 1500});
You can also create cue points with labels by defining a label attribute:
// to create a cue point with a label
wav.setCuePoint({position: 1500, label: 'some label'});
To delete a cue point use WaveFile.deleteCuePoint() informing the index of the point. Points are ordered according to their position. The first point is indexed as 1.
wav.deleteCuePoint(1);
Mind that creating or deleting cue points will change the index of other points if they exist.
To list all the cue points in a file, in the order they appear:
let cuePoints = wav.listCuePoints();
This method will return a list with cue points ordered as they appear in the file.
[
{
position: 500, // the position in milliseconds
label: 'cue marker 1',
end: 1500, // the end position in milliseconds
dwName: 1,
dwPosition: 0,
fccChunk: 'data',
dwChunkStart: 0,
dwBlockStart: 0,
dwSampleOffset: 22050, // the position as a sample offset
dwSampleLength: 3646827, // the region length as a sample count
dwPurposeID: 544106354,
dwCountry: 0,
dwLanguage: 0,
dwDialect: 0,
dwCodePage: 0,
},
//...
];
Create regions in files
You can create regions using the WaveFile.setCuePoint() method. Regions are cue points with extra data.
If you define a not null end attribute in the object describing the cue point, the point will be created as a region. The end attribute should be the end of the region, in milliseconds, counting from the start of the file, and always greater than the position of the point:
// to create a region with a label:
wav.setCuePoint({position: 1500, end: 2500, label: 'some label'});
You can also define the following optional properties when creating a region:
- dwPurposeID
- dwCountry
- dwLanguage
- dwDialect
- dwCodePage
RIFX
wavefile can handle existing RIFX files and create RIFX files from scratch. Files created from scratch will default to RIFF; to create a file as RIFX you must define the container:
wav.fromScratch(1, 48000, '16', [0, 1, -3278, 327], {"container": "RIFX"});
RIFX to RIFF and RIFF to RIFX:
// Turn a RIFF file to a RIFX file
wav.toRIFX();
// Turn a RIFX file to a RIFF file
wav.toRIFF();
IMA-ADPCM
16-bit 8000 Hz mono wave files can be compressed as IMA-ADPCM:
// Encode a 16-bit wave file as 4-bit IMA-ADPCM:
wav.toIMAADPCM();
IMA-ADPCM files compressed with wavefile will have a block align of 256 bytes.
If the audio is not 16-bit it will be converted to 16-bit before compressing. Compressing audio with sample rate different from 8000 Hz or more than one channel is not supported and will thro
