tone-stream 1.3.0 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  A simple node.js tone stream library.
4
4
 
5
- You can specify frequencies to be played by adding item in the format:
5
+ You can specify frequencies to be played by adding items in the format:
6
6
  ```
7
7
  [NUMBER_OF_SAMPLES, FREQUENCY]
8
8
  ```
@@ -15,7 +15,7 @@ or DTMF tones:
15
15
  Playing some musical notes:
16
16
 
17
17
  ```
18
- const ToneStream = require('tone-stream')
18
+ const { ToneStream } = require('tone-stream')
19
19
 
20
20
  const Speaker = require('speaker')
21
21
 
@@ -29,9 +29,9 @@ const ts = new ToneStream(format)
29
29
 
30
30
  const s = new Speaker(format)
31
31
 
32
- ts.add([4000, 261.63]) // C4
33
- ts.add([4000, 296.33]) // D4
34
- ts.add([4000, 329.63]) // E4
32
+ ts.add([1000, 261.63]) // C4
33
+ ts.add([1000, 296.33]) // D4
34
+ ts.add([1000, 329.63]) // E4
35
35
 
36
36
  ts.pipe(s)
37
37
 
@@ -41,7 +41,7 @@ setTimeout(() => {}, 2000)
41
41
  Playing some DTMF tones:
42
42
 
43
43
  ```
44
- const ToneStream = require('tone-stream')
44
+ const { ToneStream } = require('tone-stream')
45
45
 
46
46
  const Speaker = require('speaker')
47
47
 
@@ -66,3 +66,46 @@ ts.pipe(s)
66
66
  setTimeout(() => {}, 2000)
67
67
  ```
68
68
 
69
+ Using some helper function to add miscelaneous tones
70
+ ```
71
+ const { ToneStream, utils } = require('tone-stream')
72
+
73
+ const Speaker = require('speaker')
74
+
75
+ const _ = require('lodash')
76
+
77
+ const SAMPLE_RATE = 8000
78
+
79
+ const format = {
80
+ sampleRate: SAMPLE_RATE,
81
+ bitDepth: 16,
82
+ channels: 1
83
+ }
84
+
85
+ const ts = new ToneStream(format)
86
+
87
+ const s = new Speaker(format)
88
+
89
+ const tones = _.flatten([
90
+ utils.gen_dtmf_tones("1234567890abcdef", 100, 0, SAMPLE_RATE),
91
+ utils.gen_morse_tones("Be yourself; everyone else is already taken", 880, 70, SAMPLE_RATE),
92
+ utils.gen_music_scale("C5 D5 E5 F5 G5 A5 B5 C6", 100, 0, SAMPLE_RATE),
93
+ ])
94
+
95
+ console.log("Inspecting tones:")
96
+ tones.forEach(tone => {
97
+ console.log(tone)
98
+ })
99
+
100
+ ts.concat(tones)
101
+
102
+ ts.on('empty', () => {
103
+ console.log("Got event 'empty'. Reversing tones and playing again.")
104
+ tones.reverse()
105
+ ts.concat(tones)
106
+ })
107
+
108
+ console.log("Starting playing tones")
109
+ ts.pipe(s)
110
+
111
+ ```
@@ -1,4 +1,4 @@
1
- const ToneStream = require('../index.js')
1
+ const { ToneStream } = require('../index.js')
2
2
  const goertzel = require('goertzel-stream')
3
3
 
4
4
  const {PassThrough} = require('stream')
@@ -1,4 +1,4 @@
1
- const ToneStream = require('../index.js')
1
+ const { ToneStream } = require('../index.js')
2
2
  const Speaker = require('speaker')
3
3
 
4
4
  const format = {
@@ -1,4 +1,4 @@
1
- const ToneStream = require('../index.js')
1
+ const { ToneStream } = require('../index.js')
2
2
  const Speaker = require('speaker')
3
3
 
4
4
  const format = {
@@ -0,0 +1,26 @@
1
+ const { ToneStream, utils } = require('../index.js')
2
+ const Speaker = require('speaker')
3
+
4
+ const SAMPLE_RATE = 8000
5
+
6
+ const format = {
7
+ sampleRate: SAMPLE_RATE,
8
+ bitDepth: 16,
9
+ channels: 1
10
+ }
11
+
12
+ const ts = new ToneStream(format)
13
+
14
+ const s = new Speaker(format)
15
+
16
+ var tones = utils.gen_dtmf_tones("1234576890abcd*#", 50, 50, SAMPLE_RATE)
17
+
18
+ ts.concat(tones)
19
+
20
+ ts.on('empty', () => {
21
+ console.log("Got event 'empty'. Reversing tones.")
22
+ tones.reverse()
23
+ ts.concat(tones)
24
+ })
25
+
26
+ ts.pipe(s)
@@ -0,0 +1,27 @@
1
+ const { ToneStream, utils } = require('../index.js')
2
+ const Speaker = require('speaker')
3
+
4
+ const SAMPLE_RATE = 8000
5
+
6
+ const format = {
7
+ sampleRate: SAMPLE_RATE,
8
+ bitDepth: 16,
9
+ channels: 1
10
+ }
11
+
12
+ const ts = new ToneStream(format)
13
+
14
+ const s = new Speaker(format)
15
+
16
+ var tones = utils.gen_morse_tones("What we've got here is failure to communicate", "C6", 70, SAMPLE_RATE)
17
+ tones.push([8000, 's'])
18
+
19
+ ts.concat(tones)
20
+
21
+ ts.on('empty', () => {
22
+ console.log("Got event 'empty'. Reversing tones.")
23
+ tones.reverse()
24
+ ts.concat(tones)
25
+ })
26
+
27
+ ts.pipe(s)
@@ -1,8 +1,10 @@
1
- const ToneStream = require('../index.js')
1
+ const { ToneStream, utils } = require('../index.js')
2
2
  const Speaker = require('speaker')
3
3
 
4
+ const SAMPLE_RATE = 8000
5
+
4
6
  const format = {
5
- sampleRate: 8000,
7
+ sampleRate: SAMPLE_RATE,
6
8
  bitDepth: 16,
7
9
  channels: 1
8
10
  }
@@ -11,23 +13,18 @@ const ts = new ToneStream(format)
11
13
 
12
14
  const s = new Speaker(format)
13
15
 
14
- var notes = [
15
- [1000, 261.63], // C4
16
- [1000, 296.33], // D4
17
- [1000, 329.63], // E4
18
- [1000, 349.23], // F4
19
- [1000, 392.00], // G4
20
- [1000, 440.00], // A4
21
- [1000, 493.88], // B4
22
- [1000, 523.25], // C5
23
- ]
16
+ const notes = "C4 D4 E4 F4 G4 A4 B4 C5"
17
+ const note_duration = 100 // milliseconds
18
+ const rest_duration = 0 // milliseconds
19
+
20
+ const tones = utils.gen_music_scale(notes, note_duration, rest_duration, SAMPLE_RATE)
24
21
 
25
- ts.concat(notes)
22
+ ts.concat(tones)
26
23
 
27
24
  ts.on('empty', () => {
28
25
  console.log("Got event 'empty'. Reversing notes.")
29
- notes.reverse()
30
- ts.concat(notes)
26
+ tones.reverse()
27
+ ts.concat(tones)
31
28
  })
32
29
 
33
30
  ts.pipe(s)
@@ -1,4 +1,4 @@
1
- const ToneStream = require('../index.js')
1
+ const { ToneStream } = require('../index.js')
2
2
 
3
3
  const Speaker = require('speaker')
4
4
 
package/index.js CHANGED
@@ -153,4 +153,7 @@ class ToneStream extends Readable {
153
153
  }
154
154
  }
155
155
 
156
- module.exports = ToneStream
156
+ module.exports = {
157
+ ToneStream,
158
+ utils: require('./lib/utils.js'),
159
+ }
package/lib/dtmf.js CHANGED
@@ -22,6 +22,11 @@ tones['a'] = tones['A']
22
22
  tones['b'] = tones['B']
23
23
  tones['c'] = tones['C']
24
24
  tones['d'] = tones['D']
25
+ tones['e'] = tones['*']
26
+ tones['f'] = tones['#']
27
+ tones['E'] = tones['*']
28
+ tones['F'] = tones['#']
29
+
25
30
 
26
31
 
27
32
  module.exports = tones
package/lib/utils.js ADDED
@@ -0,0 +1,111 @@
1
+ const morse = require('morse-node').create("ITU")
2
+
3
+ const noteToFrequency = require('note-to-frequency')
4
+
5
+ const tone2freq = tone => {
6
+ if(typeof tone === 'number') {
7
+ return tone
8
+ }
9
+ return noteToFrequency(tone)
10
+ }
11
+
12
+ const wpm2rate = (wpm, sampleRate) => {
13
+ // WPM = 2.4 * (Dots per second)
14
+ // Ref: http://www.nu-ware.com/NuCode%20Help/index.html?morse_code_structure_and_timing_.htm
15
+ var dots_per_second = wpm / 2.4
16
+ return sampleRate / dots_per_second
17
+ }
18
+
19
+ const gen_morse_tones = (text, freq_tone, wpm, sampleRate) => {
20
+ if(!morse.isValid(text, 'chars')) {
21
+ throw `parse-failure: invalid chars`
22
+ }
23
+
24
+ var signals = morse.encode(text)
25
+
26
+ signals = signals.replace(/ \/ /g, "/")
27
+
28
+ var dot_duration = Math.round(wpm2rate(wpm, sampleRate)) // converts from WPM to number of samples
29
+ var dash_duration = dot_duration * 3
30
+ var word_space_duration = dot_duration * 7
31
+
32
+ var tone = tone2freq(freq_tone)
33
+
34
+ var last_was_dot_or_dash = false
35
+
36
+ var tones = []
37
+
38
+ for(var i=0 ; i<signals.length ; i++) {
39
+ var signal = signals[i]
40
+ if(last_was_dot_or_dash && (signal == '.'|| signal == '-')) {
41
+ tones.push([dot_duration, 's']) // silence
42
+ }
43
+ switch(signal) {
44
+ case '.':
45
+ tones.push([dot_duration, tone])
46
+ last_was_dot_or_dash = true
47
+ break
48
+ case '-':
49
+ tones.push([dash_duration, tone])
50
+ last_was_dot_or_dash = true
51
+ break
52
+ case ' ':
53
+ tones.push([dash_duration, 's']) // silence
54
+ last_was_dot_or_dash = false
55
+ break
56
+ case '/':
57
+ tones.push([word_space_duration, 's']) // silence
58
+ last_was_dot_or_dash = false
59
+ break
60
+ }
61
+ }
62
+
63
+ return tones
64
+ }
65
+
66
+ const gen_dtmf_tones = (digits, digit_duration, interdigit_duration, sampleRate) => {
67
+ if(!digits.match(/^[0123456789abcdefABCDEF\*#]+/)) {
68
+ throw `parse-failure: invalid DTMF digits`
69
+ }
70
+
71
+ var samples_per_digit = Math.round(digit_duration * sampleRate / 1000)
72
+ var samples_per_rest = Math.round(interdigit_duration * sampleRate / 1000)
73
+
74
+ var tones = []
75
+
76
+ for (var i=0 ; i<digits.length; i++) {
77
+ if(i > 0) {
78
+ tones.push([samples_per_rest, 's'])
79
+ }
80
+ tones.push([samples_per_digit, 'DTMF:' + digits.charAt(i)])
81
+ }
82
+
83
+ return tones
84
+ }
85
+
86
+ const gen_music_scale = (notes, note_duration, rest_duration, sampleRate) => {
87
+ var tones = []
88
+
89
+ var samples_per_note = Math.round(note_duration * sampleRate / 1000)
90
+ var samples_per_rest = Math.round(rest_duration * sampleRate / 1000)
91
+
92
+ var notes = notes.split(" ")
93
+
94
+ for (var i=0 ; i<notes.length; i++) {
95
+ var note = notes[i]
96
+ if(i > 0) {
97
+ tones.push([samples_per_rest, 's'])
98
+ }
99
+ var freq = noteToFrequency(note)
100
+ tones.push([samples_per_note, freq])
101
+ }
102
+
103
+ return tones
104
+ }
105
+
106
+
107
+ module.exports = {
108
+ gen_morse_tones,
109
+ gen_dtmf_tones,
110
+ gen_music_scale,
111
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tone-stream",
3
- "version": "1.3.0",
3
+ "version": "1.4.2",
4
4
  "description": "A simple audio tone stream library",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -9,16 +9,25 @@
9
9
  },
10
10
  "keywords": [
11
11
  "tone",
12
- "stream"
12
+ "stream",
13
+ "dtmf",
14
+ "morse",
15
+ "music",
16
+ "notes",
17
+ "audio",
18
+ "frequency"
13
19
  ],
14
20
  "scripts": {},
15
21
  "author": "MayamaTakeshi",
16
22
  "license": "MIT",
17
23
  "devDependencies": {
18
24
  "goertzel-stream": "git+https://github.com/MayamaTakeshi/goertzel-stream.git",
25
+ "lodash": "^4.17.21",
19
26
  "speaker": "^0.5.1"
20
27
  },
21
28
  "dependencies": {
29
+ "morse-node": "^0.1.1",
30
+ "note-to-frequency": "^1.4.1",
22
31
  "spec-read-stream": "^1.2.0"
23
32
  }
24
33
  }
package/a.js DELETED
@@ -1,54 +0,0 @@
1
- const ToneStream = require('./index.js')
2
-
3
- const Speaker = require('speaker')
4
-
5
- const assert = require('assert')
6
-
7
- const format = {
8
- sampleRate: 8000,
9
- bitDepth: 16,
10
- channels: 1
11
- }
12
-
13
- const filler = 0// silence
14
-
15
- const ts = new ToneStream(format) //, filler)
16
-
17
- const s = new Speaker(format)
18
-
19
- ts.add([3000, 261.63]) // C4
20
- ts.add([1000, 's'])
21
- ts.add([3000, 296.33]) // D4
22
- ts.add([1000, 's'])
23
- ts.add([3000, 329.63]) // E4
24
-
25
- var b
26
- /*
27
- b= ts.read(500)
28
- console.log(b.length, b)
29
- assert(b.length == 500)
30
- s.write(b)
31
-
32
- b = ts.read(700)
33
- console.log(b.length, b)
34
- assert(b.length == 700)
35
- s.write(b)
36
-
37
- b = ts.read(160)
38
- console.log(b.length, b)
39
- assert(b.length == 160)
40
- s.write(b)
41
-
42
- b = ts.read(180)
43
- console.log(b.length, b)
44
- assert(b.length == 180)
45
- s.write(b)
46
- */
47
-
48
- b = ts.read(12000)
49
- console.log(b.length, b)
50
- //assert(b.length == 10080) // this will be filled with zeros after all items are consumed.
51
- s.write(b)
52
-
53
- setTimeout(() => {}, 2000)
54
-
package/a.raw DELETED
Binary file
package/a.txt DELETED
@@ -1,3 +0,0 @@
1
- abc
2
- def
3
- ghi
package/a1.js DELETED
@@ -1,23 +0,0 @@
1
- const ToneStream = require('./index.js')
2
-
3
- const Speaker = require('speaker')
4
-
5
- const format = {
6
- sampleRate: 8000,
7
- bitDepth: 16,
8
- channels: 1
9
- }
10
-
11
- const ts = new ToneStream(format)
12
-
13
- const s = new Speaker(format)
14
-
15
- ts.add([1000, 'DTMF:1'])
16
- ts.add([500, 's'])
17
- ts.add([1000, 'DTMF:2'])
18
- ts.add([500, 's'])
19
- ts.add([1000, 'DTMF:3'])
20
-
21
- ts.pipe(s)
22
-
23
- setTimeout(() => {}, 2000)
package/b.js DELETED
@@ -1,22 +0,0 @@
1
- const ToneStream = require('./index.js')
2
- const Speaker = require('speaker')
3
-
4
- const format = {
5
- sampleRate: 8000,
6
- bitDepth: 16,
7
- channels: 1
8
- }
9
-
10
- const ts = new ToneStream(format)
11
-
12
- const s = new Speaker(format)
13
-
14
- ts.add([1570, 261.63]) // C4
15
- ts.add([1000, 's']) // silence
16
- ts.add([1570, 296.33]) // D4
17
- ts.add([1000, 's']) // silence
18
- ts.add([1570, 329.63]) // E4
19
-
20
- ts.pipe(s)
21
-
22
- setTimeout(() => {}, 2000)
package/b.raw DELETED
Binary file
package/c.js DELETED
@@ -1,29 +0,0 @@
1
- const ToneStream = require('./index.js')
2
- const Speaker = require('speaker')
3
-
4
- const format = {
5
- sampleRate: 8000,
6
- bitDepth: 16,
7
- channels: 1
8
- }
9
-
10
- const ts = new ToneStream(format, 0)
11
-
12
- const s = new Speaker(format)
13
-
14
- ts.add([500, 261.63]) // C4
15
- ts.add([250, 's']) // silence
16
- ts.add([500, 296.33]) // D4
17
- ts.add([250, 's']) // silence
18
- ts.add([500, 329.63]) // E4
19
-
20
- ts.pipe(s)
21
- /*
22
- var b = ts.read(10000)
23
- console.log("b:")
24
- console.log(b)
25
- console.log(b.length, b)
26
- s.write(b)
27
- */
28
-
29
- setTimeout(() => {}, 2000)
package/d.js DELETED
@@ -1,14 +0,0 @@
1
- const ToneStream = require('./index.js')
2
-
3
- const fs = require('fs')
4
-
5
- const ws = fs.createWriteStream('./a.raw')
6
-
7
- const ts = new ToneStream({
8
- sampleRate: 8000,
9
- bitDepth: 16,
10
- channels: 1
11
- })
12
-
13
- ts.pipe(ws)
14
-
package/e.js DELETED
@@ -1,9 +0,0 @@
1
-
2
- var fs =require('fs')
3
- var spy = new require('stream').PassThrough()
4
- spy.on('data', data=> {
5
- console.log("got data")
6
- console.log(data)
7
- })
8
-
9
- fs.createReadStream("a.txt").pipe(spy).pipe(process.stdout)
package/f.js DELETED
@@ -1,41 +0,0 @@
1
- const ToneStream = require('./index.js')
2
-
3
- const Speaker = require('speaker')
4
-
5
- const assert = require('assert')
6
-
7
- const format = {
8
- sampleRate: 8000,
9
- bitDepth: 16,
10
- channels: 1
11
- }
12
-
13
- const filler = 0 // silence
14
-
15
- const ts = new ToneStream(format, filler)
16
-
17
- const s = new Speaker(format)
18
-
19
- ts.add([2000, 261.63]) // C4
20
- ts.add([2000, 296.33]) // D4
21
- ts.add([2000, 329.63]) // E4
22
-
23
- const fetch_and_write = () => {
24
- var res = true
25
- while(res) {
26
- var b = ts.read(160)
27
- if(!b) return
28
- console.log(b.length, b)
29
- var res = s.write(b)
30
- console.log(res)
31
- }
32
- }
33
-
34
- s.on('drain', () => {
35
- console.log('drain')
36
- fetch_and_write()
37
- })
38
-
39
- fetch_and_write()
40
-
41
- setTimeout(() => {}, 5000)
package/g.js DELETED
@@ -1,29 +0,0 @@
1
-
2
-
3
- var goertzel = require('goertzel-stream')
4
- var Generator = require('audio-generator')
5
-
6
- var freq = 261.63
7
-
8
- // Generate a sine wave at 697 Hz
9
- var gen = Generator(function (time) {
10
- if (time > 1) {
11
- return 0
12
- } else {
13
- return Math.sin(Math.PI * 2 * time * freq)
14
- }
15
- })
16
-
17
- // Detection stream looking for the 697 Hz frequency
18
- var detect = goertzel([freq, 296.33, 329.63])
19
-
20
- // Pipe the signal into the detector
21
- gen.pipe(detect)
22
-
23
- detect.on('toneStart', function (tones) {
24
- console.log('start', tones)
25
- })
26
- detect.on('toneEnd', function (tones) {
27
- console.log('start', tones)
28
- })
29
-
package/g1.js DELETED
@@ -1,48 +0,0 @@
1
-
2
-
3
- var goertzel = require('goertzel-stream')
4
- var Generator = require('audio-generator')
5
-
6
- var lo = 697
7
- //var hi = 1209
8
-
9
- var gen = Generator(function (time) {
10
- if (time > 1) {
11
- return 0
12
- } else {
13
- return (
14
- //(
15
- Math.sin(Math.PI * 2 * time * lo)
16
- // +
17
- // Math.sin(Math.PI * 2 * time * hi)
18
- //) / 2
19
- )
20
- }
21
- },
22
- {
23
- duration: 10,
24
- period: Infinity,
25
- }
26
- )
27
-
28
- // Detection stream looking for the 697 Hz frequency
29
- var detect = goertzel([697, 770, 852, 941, 1209, 1336, 1477, 1633])
30
-
31
- // Pipe the signal into the detector
32
- gen.pipe(detect)
33
-
34
- var Speaker = require('speaker')
35
- var s = new Speaker({
36
- sampleRate: 32000,
37
- bitDepth: 16,
38
- channels: 1,
39
- })
40
- //gen.pipe(s)
41
-
42
- detect.on('toneStart', function (tones) {
43
- console.log('start', tones)
44
- })
45
- detect.on('toneEnd', function (tones) {
46
- console.log('start', tones)
47
- })
48
-
package/h.js DELETED
@@ -1,65 +0,0 @@
1
- var Generator = require('audio-generator/stream');
2
- var Speaker = require('speaker');
3
-
4
- var speaker = new Speaker({
5
- sampleRate: 44100,
6
- bitDepth: 16,
7
- channels: 2,
8
- })
9
-
10
- var fs = require('fs')
11
-
12
- var ws = fs.createWriteStream("./b.raw")
13
-
14
- Generator(
15
- //Generator function, returns sample values -1..1 for channels
16
- function (time) {
17
- /*
18
- return [
19
- Math.sin(Math.PI * 2 * time * 439), //channel 1
20
- Math.sin(Math.PI * 2 * time * 441), //channel 2
21
- ]
22
- */
23
- return [
24
- Math.sin(Math.PI * 2 * time * 440),
25
- Math.sin(Math.PI * 2 * time * 440),
26
- ]
27
- },
28
-
29
- {
30
- //Duration of generated stream, in seconds, after which stream will end.
31
- duration: 3,
32
-
33
- //Periodicity of the time.
34
- period: Infinity,
35
- })
36
- .on('error', function (e) {
37
- //error happened during generation the frame
38
- })
39
- .on('data', function(audioBuffer) {
40
- var cd = audioBuffer.getChannelData(0)
41
- //console.log(cd)
42
- var b = Buffer.alloc(cd.length * 2)
43
- for(var i=0 ; i<cd.length ; i++) {
44
- //if(cd[i] != 0) console.log(cd[i])
45
-
46
- var f = cd[i]
47
- var OLD_LIMIT = 0.9999999999999999
48
-
49
- f = (32767 - -32768)/(OLD_LIMIT - -OLD_LIMIT)*(f - OLD_LIMIT)+32767
50
-
51
- //if(f != 0) { console.log(f) }
52
- b.writeInt16LE(f, i*2)
53
- }
54
- //console.log(b.length, b)
55
- // speaker.write(b)
56
- ws.write(b)
57
- })
58
- /*
59
- .pipe(speaker);
60
- .pipe(ws)
61
- */
62
-
63
-
64
-
65
-
package/i.js DELETED
@@ -1,29 +0,0 @@
1
- const ToneStream = require('./index.js')
2
- const Speaker = require('speaker')
3
-
4
- const format = {
5
- sampleRate: 8000,
6
- bitDepth: 16,
7
- channels: 1
8
- }
9
-
10
- const ts = new ToneStream(format)
11
-
12
- const s = new Speaker(format)
13
-
14
- ts.add([1000, 's']) // silence
15
- ts.add([2000, 261.63]) // C4
16
- ts.add([1000, 's']) // silence
17
- ts.add([2000, 296.33]) // D4
18
- ts.add([1000, 's']) // silence
19
- ts.add([2000, 329.63]) // E4
20
-
21
- var tid = setInterval(() => {
22
- var b = ts.read(320)
23
- console.log(b)
24
- if(!b) {
25
- clearInterval(tid)
26
- return
27
- }
28
- s.write(b)
29
- }, 20)