This thing generates raw PCM data, specified by a frequency and length in seconds.
volume and sampleRate are optional, the default is shown above. If you want to specify sampleRate, you have to specify volume!
var tone = ;var A440 = ; // get PCM data for a 440hz A, 20 seconds, volume 30var A440_low_sample = ; // this array has lower sample rate and will only be half as long
The data is returned as a normal array, so you can do operations on it.
// An A-major chordvar tone1 =var tone2 =var tone3 =// "playing" one tone at the time// note that at this time, our sound is just an array// of gain values. By appending the raw PCM data for one after another,// we can play them in a sequencevar res = tone1// By adding values of the tones for each sample,// we play them simultaneously, as a chordforvar i = 0; i < tone1length; i++res
The meaning of the 'volume' value depends on whether you're creating 8-bit or 16-bit data. For 8-bit data, the max volume to avoid distortion is 128. For 16-bit data, the max volume is 32768. Those values are available as require('tonegenerator').MAX_8 and require('tonegenerator').MAX_16 respectively.
Before writing your PCM data to a file, you need to convert it to a buffer of UInt8 values. 8-bit wave data goes from 0-255, so we need to add 128 to each value:
var tone = ;// Use this package to write a header for the wave file//var header = ;var fs = ;var file = fsvar samples =file// Convert -128 -> 127 range into 0 -> 255var data = Uint8Arrayif Bufferfrom // Node 5+buffer = Bufferelsebuffer = datafilefile
16-bit data requires a little bit more work, since we need to take Endianess into account. Unlike 8-bit data, the volumes does not start at 0, but at -32768.
All the references to data length need to be doubled.
var tone = ;var header = ;var fs = ;var file = fsvar samples =filevar data = Int16Arrayvar size = datalength * 2 // 2 bytes per sampleif BufferallocUnsafe // Node 5+buffer = Bufferelsebuffer = sizedatafilefile
In stereo wave data, the sample for each channel comes right after each other.
The principle looks like
[sample0-1 sample0-2 sample1-1 sample1-2]. So we need to
first generate the data for each channel, then interleave them.
var tone = ;var header = ;var fs = ;var file = fs// A loud A for channel 1var channel1 =// A not so loud C for channel 2var channel2 =// create an array where the 2 channels are interleaved:var samples =for var i = 0; i < channel1length; i++samplessamplesfilevar data = Int16Arrayvar size = datalength * 2 // 2 bytes per sampleif BufferallocUnsafe // Node 5+buffer = Bufferelsebuffer = sizedatafilefile