Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

tonegenerator

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tonegenerator - npm Package Compare versions

Comparing version 0.2.1 to 0.3.0

73

index.js

@@ -6,7 +6,48 @@ /*

*/
function generateCycle(cycle, volume) {
var shapes = {
sine: function (i, cycle, volume) {
// i / cycle => value between 0 and 1
// 0 = beginning of circly
// 0.25 Math.sin = 1
// 0.5 Math.sin = 0
// 0.75 Math.sin = -1
// 1 Math.sin = 1
return Math.min(volume * Math.sin((i/cycle) * Math.PI * 2), volume - 1);
},
triangle: function (i, cycle, volume) {
var halfCycle = cycle / 2
var level
if (i < halfCycle) {
level = (volume * 2) * (i / halfCycle) - volume;
} else {
i = i - halfCycle
level = -(volume * 2) * (i / halfCycle) + volume;
}
return Math.min(level, volume - 1);
},
saw: function (i, cycle, volume) {
return Math.min((volume * 2) * (i / cycle) - volume, volume - 1);
},
square: function (i, cycle, volume) {
if(i > cycle / 2) {
return volume - 1;
}
return -volume;
}
}
function generateCycle(cycle, volume, shape) {
var data = [];
var tmp;
var generator = typeof shape == 'function' ? shape : shapes[shape];
if (!generator) {
throw new Error('Invalid wave form: "' + shape + '" choose between: ' + Object.keys(shapes));
}
for(var i = 0; i < cycle; i++) {
tmp = Math.min(volume * Math.sin((i/cycle) * Math.PI * 2), volume - 1)
tmp = generator(i, cycle, volume);
data[i] = Math.round(tmp);

@@ -17,7 +58,9 @@ }

module.exports = function(freq, lengthInSecs, volume, rate) {
freq = freq || 440;
rate = rate || 44100
lengthInSecs = lengthInSecs || 2.0;
volume = volume || 30
function generateWaveForm(opts) {
opts = opts || {}
var freq = opts.freq || 440;
var rate = opts.rate || 44100
var lengthInSecs = opts.lengthInSecs || 2.0;
var volume = opts.volume || 30;
var shape = opts.shape || 'sine';

@@ -30,3 +73,3 @@ var cycle = Math.floor(rate/freq);

for(var i = 0; i < cycles; i++) {
ret = ret.concat(generateCycle(cycle, volume));
ret = ret.concat(generateCycle(cycle, volume, shape));
}

@@ -37,3 +80,17 @@

module.exports = function() {
// to support both old interface and the new one:
var opts = arguments[0]
if (arguments.length > 1 && typeof opts === "number") {
opts = {}
opts.freq = arguments[0]
opts.lengthInSecs = arguments[1]
opts.volume = arguments[2]
opts.rate = arguments[3]
}
return generateWaveForm(opts)
}
module.exports.MAX_16 = 32768;
module.exports.MAX_8 = 128;

2

package.json
{
"name": "tonegenerator",
"description": "Generates a tone as raw PCM WAV data, so you can do operations on it",
"version": "0.2.1",
"version": "0.3.0",
"scripts": {

@@ -6,0 +6,0 @@ "test": "node test.js",

ToneGenerator for node.js
====
This thing generates raw PCM data, specified by
a frequency and length in seconds.
This thing generates an array of numbers in waveforms. This waveform can be written into a wavefile as raw PCM data.
It does not play the sounds. If you want to play sounds, make sure to read the examples on how to write wave files below.

@@ -10,13 +10,38 @@ ## Generating Tones:

```javascript
tone(frequency, lengthInSeconds, volume = 30, sampleRate = 44100)
var tone = require('tonegenerator')
// New Interface! More options!!
var tonedata = tone({
freq: 440,
lengthInSecs: 2.0,
volume: 30,
sampleRate: 44100,
shape: 'triangle'
})
// The old interface, still available for compatibility
var tonedata = tone(frequency, lengthInSeconds, volume = 30, sampleRate = 44100)
```
#### Using the new interface
- **freq** frequency in hertz. *defaults to 440*
- **lengthInSecs** controls the length of the array output together with the samplerate *defaults to 2.0*
- **volume** controls max/min for the array values. If you intend to write 8-bit it should be less than or equal to tone.MAX_8, if 16 bit it should be less than or equal to tone.MAX_16. *defaults to 30*
- **sampleRate** number of samples per second. Together with lengthInSecs, this define the length of the output array (lengthInSeccs * sampleRate). *defaults to 44100*
- **shape** controls the wave shape. Options are *'triangle', 'square', 'sine', 'saw'*. You can also pass in a custom function, see the tests for an example of this. *defaults to 'sine'*
#### Using the old interface
The old interface takes four arguments: *freq, lengthInSecs, volume, sampleRate*.
**volume** and **sampleRate** are optional, the default is shown above.
**If you want to specify sampleRate, you have to specify volume!**
**Shape is not available in the old interface. If you want to specify sampleRate, you have to specify volume!**
#### Useful constants
```javascript
tone.MAX_8 // max volume to be used with 8-bit sound
tone.MAX_16 // max volume for 16 bit sound
```javascript
var tone = require('tonegenerator');
var A440 = tone(440, 20, 30); // get PCM data for a 440hz A, 20 seconds, volume 30
var A440_low_sample = tone(440, 20, 30, 22050); // this array has lower sample rate and will only be half as long
var A440 = tone({ freq: 440, lengthInSeconds: 20, volume: 30 }); // get PCM data for a 440hz A, 20 seconds, volume 30
var A440_low_sample = tone(440, 20, 30, 22050); // (old interface) this array has lower sample rate and will only be half as long
```

@@ -30,5 +55,5 @@

// An A-major chord
var tone1 = tone(440, 2, 60)
var tone2 = tone(554.37, 2, 30)
var tone3 = tone(659.26, 2, 30)
var tone1 = tone({ freq: 440, lengthInSecs: 2, volume: 60 })
var tone2 = tone({ freq: 554.37, lengthInSecs: 2, volume: 30 })
var tone3 = tone({ freq: 659.26, lengthInSecs: 2, volume: 30 })

@@ -63,3 +88,3 @@ // "playing" one tone at the time

var file = fs.createWriteStream('8bit-example.wav')
var samples = tone(440, 2, tone.MAX_8)
var samples = tone({ freq: 440, lengthInSecs: 2, volume: tone.MAX_8 })

@@ -96,3 +121,3 @@ file.write(header(samples.length, {

var file = fs.createWriteStream('16bit-example.wav')
var samples = tone(440, 2, tone.MAX_16)
var samples = tone({ freq: 440, lengthInSecs: 2, volume: tone.MAX_16 })

@@ -134,5 +159,5 @@ file.write(header(samples.length * 2, {

// A loud A for channel 1
var channel1 = tone(440, 2, tone.MAX_16)
var channel1 = tone({ freq: 440, lengthInSecs: 2, volume: tone.MAX_16 })
// A not so loud C for channel 2
var channel2 = tone(554.37, 2, tone.MAX_16 / 4)
var channel2 = tone({ freq: 554.37, lengthInSecs: 2, volume: tone.MAX_16 / 4 })

@@ -139,0 +164,0 @@ // create an array where the 2 channels are interleaved:

@@ -7,6 +7,8 @@ var assert = require('assert')

var tone1 = tonegenerator(440, 2, 10)
var tone2 = tonegenerator(440, 2, 30)
var tonefrequency = tonegenerator(440, 2, 10, 22050)
var tone1 = tonegenerator({ freq: 440, lengthInSecs: 2, volume: 10 })
var tone2 = tonegenerator({ freq: 440, lengthInSecs: 2, volume: 30 })
var tonefrequency = tonegenerator({ freq: 440, lengthInSecs: 2, volume: 10, rate: 22050 })
console.log('Testing Sine Waves')
assert(Array.isArray(tone1), 'Data is an array')

@@ -23,2 +25,64 @@

console.log('Testing Triangle Waves')
var tone4 = tonegenerator({ freq: 440, lengthInSecs: 2, volume: 10, shape: 'triangle' })
// test that max is correct
assert.strictEqual(Math.max.apply(Math, tone4), 9)
// test that min is correct
assert.strictEqual(Math.min.apply(Math, tone4), -10)
// test that there are intermediate values
assert(tone4.includes(0))
assert(tone4.includes(-1))
console.log('Testing Saw Waves')
var tone5 = tonegenerator({ freq: 440, lengthInSecs: 2, volume: 10, shape: 'saw' })
// test first val, should be min
assert.strictEqual(tone5.shift(), -10)
// test last val, should be max
assert.strictEqual(tone5.pop(), 9)
// test that there's intermediate values generated
assert(tone5.includes(0))
console.log('Testing Square Waves')
var tone6 = tonegenerator({ freq: 440, lengthInSecs: 2, volume: 10, shape: 'square' })
// test first val
assert.strictEqual(tone6.pop(), 9)
// test last val
assert.strictEqual(tone6.shift(), -10)
// make sure there's no intermediate values
assert(!tone6.includes(0))
console.log('Testing Custom Waves')
var tone7 = tonegenerator({
freq: 440,
lengthInSecs: 2,
volume: 11,
shape: function (i, cycle, volume) {
return volume - 1;
}
})
// test first val
assert.strictEqual(tone7.pop(), 10)
// test last val
assert.strictEqual(tone7.shift(), 10)
// make sure there's no intermediate values
assert(!tone7.includes(0))
console.log('Testing old-style interface')
var tone8 = tonegenerator(440, 2, 10)
var tone9 = tonegenerator(440, 2, 30)
var tonefrequency2 = tonegenerator(440, 2, 10, 22050)
// takes the volume argument - 1 as max
assert.strictEqual(Math.max.apply(Math, tone8), 9)
// takes the volume argument as min
assert.strictEqual(Math.min.apply(Math, tone8), -10)
// takes the volume argument as max
assert.strictEqual(Math.max.apply(Math, tone9), 29)
assert.equal(tone8.length/2, tonefrequency2.length, 'when halving audio sampling rate, the array length should be half of default')
console.log('...done')
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc