@lls/lls-audio 0.0.72 → 0.0.74

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lls/lls-audio",
3
- "version": "0.0.72",
3
+ "version": "0.0.74",
4
4
  "main": "index.js",
5
5
  "devDependencies": {
6
6
  "@kadira/storybook": "2.21.0",
@@ -5,126 +5,136 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  var AudioWorker = function AudioWorker(self) {
7
7
  var recLength = 0;
8
+ var buffersToProcess = [];
8
9
  var recBuffers = [];
9
10
  var audioBlob = null;
10
11
 
11
- self.onmessage = function (e) {
12
- var mergeBuffers = function mergeBuffers(recBuffers, recLength) {
13
- var result = new Float32Array(recLength);
14
- var offset = 0;
15
- for (var i = 0; i < recBuffers.length; i++) {
16
- result.set(recBuffers[i], offset);
17
- offset += recBuffers[i].length;
18
- }
19
- return result;
20
- };
21
-
22
- var appendBuffer = function appendBuffer(timestamp, inputBuffer) {
23
- for (var channel = 0; channel < inputBuffer.length; channel++) {
24
- if (!recBuffers[channel]) recBuffers[channel] = [];
25
- recBuffers[channel].push({ timestamp: timestamp, data: inputBuffer[channel], length: inputBuffer[channel].length });
26
- }
27
- recLength += inputBuffer[0].length;
28
- };
29
-
30
- function interleave(inputL, inputR) {
31
- var length = inputL.length + inputR.length;
32
- var result = new Float32Array(length);
33
-
34
- var index = 0;
35
- var inputIndex = 0;
36
-
37
- while (index < length) {
38
- result[index++] = inputL[inputIndex];
39
- result[index++] = inputR[inputIndex];
40
- inputIndex++;
41
- }
42
- return result;
12
+ var processBuffers = function processBuffers() {
13
+ buffersToProcess.forEach(function (_ref) {
14
+ var timestamp = _ref.timestamp,
15
+ inputBuffer = _ref.inputBuffer;
16
+
17
+ appendBuffer(timestamp, inputBuffer);
18
+ });
19
+ };
20
+
21
+ var mergeBuffers = function mergeBuffers(recBuffers, recLength) {
22
+ var result = new Float32Array(recLength);
23
+ var offset = 0;
24
+ for (var i = 0; i < recBuffers.length; i++) {
25
+ result.set(recBuffers[i], offset);
26
+ offset += recBuffers[i].length;
43
27
  }
28
+ return result;
29
+ };
44
30
 
45
- var writeString = function writeString(view, offset, string) {
46
- for (var i = 0; i < string.length; i++) {
47
- view.setUint8(offset + i, string.charCodeAt(i));
48
- }
49
- };
50
-
51
- var floatTo16BitPCM = function floatTo16BitPCM(output, offset, input) {
52
- for (var i = 0; i < input.length; i++, offset += 2) {
53
- var s = Math.max(-1, Math.min(1, input[i]));
54
- output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
55
- }
56
- };
57
-
58
- var encodeWAV = function encodeWAV(samples) {
59
- var buffer = new ArrayBuffer(44 + samples.length * 2);
60
- var view = new DataView(buffer);
61
-
62
- /* RIFF identifier */
63
- writeString(view, 0, 'RIFF');
64
- /* RIFF chunk length */
65
- view.setUint32(4, 36 + samples.length * 2, true);
66
- /* RIFF type */
67
- writeString(view, 8, 'WAVE');
68
- /* format chunk identifier */
69
- writeString(view, 12, 'fmt ');
70
- /* format chunk length */
71
- view.setUint32(16, 16, true);
72
- /* sample format (raw) */
73
- view.setUint16(20, 1, true);
74
- /* channel count */
75
- view.setUint16(22, recBuffers.length, true);
76
- /* sample rate */
77
- view.setUint32(24, 44100, true);
78
- /* byte rate (sample rate * block align) */
79
- view.setUint32(28, 44100 * recBuffers.length * 2, true);
80
- /* block align (channel count * bytes per sample) */
81
- view.setUint16(32, recBuffers.length * 2, true);
82
- /* bits per sample */
83
- view.setUint16(34, 16, true);
84
- /* data chunk identifier */
85
- writeString(view, 36, 'data');
86
- /* data chunk length */
87
- view.setUint32(40, samples.length * 2, true);
88
-
89
- floatTo16BitPCM(view, 44, samples);
90
-
91
- return view;
92
- };
93
-
94
- var exportWAV = function exportWAV(beginning, end) {
95
- var buffers = [];
96
- for (var channel = 0; channel < recBuffers.length; channel++) {
97
- var length = 0;
98
- var filtredRecBuffers = recBuffers[channel].filter(function (buffer) {
99
- return buffer.timestamp >= beginning - 1000 && buffer.timestamp <= end;
100
- }).map(function (buffer) {
101
- length += buffer.length;
102
- return buffer.data;
103
- });
104
- buffers.push(mergeBuffers(filtredRecBuffers, length));
105
- }
106
- var interleaved = recBuffers.length === 2 ? interleave(buffers[0], buffers[1]) : buffers[0];
107
- var dataview = encodeWAV(interleaved);
108
- audioBlob = new Blob([dataview], { type: 'audio/wav' });
109
- };
31
+ var appendBuffer = function appendBuffer(timestamp, inputBuffer) {
32
+ for (var channel = 0; channel < inputBuffer.length; channel++) {
33
+ if (!recBuffers[channel]) recBuffers[channel] = [];
34
+ recBuffers[channel].push({ timestamp: timestamp, data: inputBuffer[channel], length: inputBuffer[channel].length });
35
+ }
36
+ recLength += inputBuffer[0].length;
37
+ };
38
+
39
+ var interleave = function interleave(inputL, inputR) {
40
+ var length = inputL.length + inputR.length;
41
+ var result = new Float32Array(length);
42
+
43
+ var index = 0;
44
+ var inputIndex = 0;
45
+
46
+ while (index < length) {
47
+ result[index++] = inputL[inputIndex];
48
+ result[index++] = inputR[inputIndex];
49
+ inputIndex++;
50
+ }
51
+ return result;
52
+ };
53
+
54
+ var writeString = function writeString(view, offset, string) {
55
+ for (var i = 0; i < string.length; i++) {
56
+ view.setUint8(offset + i, string.charCodeAt(i));
57
+ }
58
+ };
110
59
 
60
+ var floatTo16BitPCM = function floatTo16BitPCM(output, offset, input) {
61
+ for (var i = 0; i < input.length; i++, offset += 2) {
62
+ var s = Math.max(-1, Math.min(1, input[i]));
63
+ output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
64
+ }
65
+ };
66
+
67
+ var encodeWAV = function encodeWAV(samples) {
68
+ var buffer = new ArrayBuffer(44 + samples.length * 2);
69
+ var view = new DataView(buffer);
70
+
71
+ /* RIFF identifier */
72
+ writeString(view, 0, 'RIFF');
73
+ /* RIFF chunk length */
74
+ view.setUint32(4, 36 + samples.length * 2, true);
75
+ /* RIFF type */
76
+ writeString(view, 8, 'WAVE');
77
+ /* format chunk identifier */
78
+ writeString(view, 12, 'fmt ');
79
+ /* format chunk length */
80
+ view.setUint32(16, 16, true);
81
+ /* sample format (raw) */
82
+ view.setUint16(20, 1, true);
83
+ /* channel count */
84
+ view.setUint16(22, recBuffers.length, true);
85
+ /* sample rate */
86
+ view.setUint32(24, 44100, true);
87
+ /* byte rate (sample rate * block align) */
88
+ view.setUint32(28, 44100 * recBuffers.length * 2, true);
89
+ /* block align (channel count * bytes per sample) */
90
+ view.setUint16(32, recBuffers.length * 2, true);
91
+ /* bits per sample */
92
+ view.setUint16(34, 16, true);
93
+ /* data chunk identifier */
94
+ writeString(view, 36, 'data');
95
+ /* data chunk length */
96
+ view.setUint32(40, samples.length * 2, true);
97
+
98
+ floatTo16BitPCM(view, 44, samples);
99
+
100
+ return view;
101
+ };
102
+
103
+ var exportWAV = function exportWAV(beginning, end) {
104
+ processBuffers(); // append all buffers together
105
+
106
+ var buffers = [];
107
+ for (var channel = 0; channel < recBuffers.length; channel++) {
108
+ var length = 0;
109
+ var filtredRecBuffers = recBuffers[channel].filter(function (buffer) {
110
+ return buffer.timestamp >= beginning - 1000 && buffer.timestamp <= end;
111
+ }).map(function (buffer) {
112
+ length += buffer.length;
113
+ return buffer.data;
114
+ });
115
+ buffers.push(mergeBuffers(filtredRecBuffers, length));
116
+ }
117
+ var interleaved = recBuffers.length === 2 ? interleave(buffers[0], buffers[1]) : buffers[0];
118
+ var dataview = encodeWAV(interleaved);
119
+ return new Blob([dataview], { type: 'audio/wav' });
120
+ };
121
+
122
+ self.onmessage = function (e) {
111
123
  switch (e.data.command) {
112
124
  case 'append':
113
- appendBuffer(e.data.timestamp, e.data.inputBuffer);
114
- var buffers = [];
115
- for (var channel = 0; channel < recBuffers.length; channel++) {
116
- buffers.push(mergeBuffers(recBuffers[channel], recLength));
117
- }
118
- postMessage({ command: 'send_buffers', buffers: recBuffers });
125
+ buffersToProcess.push({
126
+ timestamp: e.data.timestamp,
127
+ inputBuffer: e.data.inputBuffer
128
+ });
119
129
  break;
120
130
  case 'exportWAV':
121
- exportWAV(e.data.beginning, e.data.end);
122
- postMessage({ command: 'send_WAV', audioBlob: audioBlob });
123
- break;
124
- case 'clean':
131
+ var _audioBlob = exportWAV(e.data.beginning, e.data.end);
132
+ postMessage({ command: 'send_WAV', audioBlob: _audioBlob });
133
+
134
+ // Clean variables
125
135
  recLength = 0;
126
136
  recBuffers = [];
127
- audioBlob = null;
137
+ buffersToProcess = [];
128
138
  break;
129
139
  }
130
140
  };
@@ -4,6 +4,8 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
 
7
+ var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
8
+
7
9
  var _react = require('react');
8
10
 
9
11
  var _react2 = _interopRequireDefault(_react);
@@ -13,20 +15,30 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
13
15
  var Circle = function Circle(_ref) {
14
16
  var radius = _ref.radius,
15
17
  maxRadius = _ref.maxRadius,
16
- color = _ref.color;
17
- return _react2.default.createElement('circle', { r: radius, cx: 100, cy: 100, style: { 'transition': 'all 0.1s', 'fill': 'red', opacity: 0.2 + radius / maxRadius } });
18
+ style = _ref.style;
19
+ return _react2.default.createElement('circle', { r: radius / maxRadius, style: _extends({ transition: 'all 0.1s', opacity: 0.2 + radius / maxRadius }, style) });
18
20
  };
19
21
 
20
22
  var Visualizer = function Visualizer(_ref2) {
21
- var volume = _ref2.volume;
22
-
23
- var radius = (100 + volume) / 2;
24
- radius = radius < 0 ? 0 : radius;
25
-
23
+ var _ref2$width = _ref2.width,
24
+ width = _ref2$width === undefined ? 100 : _ref2$width,
25
+ volume = _ref2.volume,
26
+ _ref2$maxRadius = _ref2.maxRadius,
27
+ maxRadius = _ref2$maxRadius === undefined ? 100 : _ref2$maxRadius,
28
+ _ref2$minRadius = _ref2.minRadius,
29
+ minRadius = _ref2$minRadius === undefined ? 50 : _ref2$minRadius,
30
+ _ref2$style = _ref2.style,
31
+ style = _ref2$style === undefined ? { fill: 'red' } : _ref2$style;
32
+
33
+ var radius = minRadius + (maxRadius - minRadius) * volume / 100;
26
34
  return _react2.default.createElement(
27
- 'svg',
28
- null,
29
- _react2.default.createElement(Circle, { radius: radius, maxRadius: 100 })
35
+ 'div',
36
+ { style: { width: width } },
37
+ _react2.default.createElement(
38
+ 'svg',
39
+ { viewBox: '-1 -1 2 2' },
40
+ _react2.default.createElement(Circle, { radius: radius, maxRadius: maxRadius, style: style })
41
+ )
30
42
  );
31
43
  };
32
44
 
package/recorder/index.js CHANGED
@@ -40,10 +40,13 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
40
40
 
41
41
  function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
42
42
 
43
- var INTERVAL = 100;
44
-
45
43
  var audioContext = new _audioContext2.default();
46
44
 
45
+ // make the volume a value between 0 and 100
46
+ var formatVolume = function formatVolume(volume) {
47
+ return Math.max(0, Math.min(100, volume + 100));
48
+ };
49
+
47
50
  var initRecorder = function initRecorder(_ref) {
48
51
  var stream = _ref.stream,
49
52
  audioContext = _ref.audioContext,
@@ -83,11 +86,12 @@ var initSpeechEvents = function initSpeechEvents(_ref3) {
83
86
  _ref3$onStoppedSpeaki = _ref3.onStoppedSpeaking,
84
87
  onStoppedSpeaking = _ref3$onStoppedSpeaki === undefined ? function () {} : _ref3$onStoppedSpeaki,
85
88
  _ref3$onVolumeChange = _ref3.onVolumeChange,
86
- onVolumeChange = _ref3$onVolumeChange === undefined ? function () {} : _ref3$onVolumeChange;
89
+ onVolumeChange = _ref3$onVolumeChange === undefined ? function () {} : _ref3$onVolumeChange,
90
+ debounce = _ref3.debounce;
87
91
 
88
92
  // Try hark
89
93
  var options = {
90
- interval: INTERVAL
94
+ interval: debounce
91
95
  //play: true // true: allow to hear the result for debug
92
96
  };
93
97
  var speechEvents = (0, _hark2.default)(stream, options);
@@ -114,7 +118,6 @@ var Recorder = function (_Component) {
114
118
 
115
119
  // Data
116
120
  _this.recordStart = null;
117
- _this.audioBuffer = [];
118
121
  _this.audioStream = null;
119
122
 
120
123
  // Methods
@@ -147,7 +150,9 @@ var Recorder = function (_Component) {
147
150
  value: function init(props) {
148
151
  var _this2 = this;
149
152
 
150
- var _props$onNotAvailable = props.onNotAvailable,
153
+ var _props$debounce = props.debounce,
154
+ debounce = _props$debounce === undefined ? 200 : _props$debounce,
155
+ _props$onNotAvailable = props.onNotAvailable,
151
156
  onNotAvailable = _props$onNotAvailable === undefined ? function () {} : _props$onNotAvailable,
152
157
  _props$onError = props.onError,
153
158
  onError = _props$onError === undefined ? function () {} : _props$onError,
@@ -164,7 +169,8 @@ var Recorder = function (_Component) {
164
169
  stream: stream,
165
170
  onError: onError,
166
171
  onVolumeChange: onVolumeChange,
167
- onRecordComplete: onRecordComplete
172
+ onRecordComplete: onRecordComplete,
173
+ debounce: debounce
168
174
  });
169
175
  }).catch(function (err) {
170
176
  onNotAvailable(err);
@@ -178,17 +184,14 @@ var Recorder = function (_Component) {
178
184
  var stream = _ref4.stream,
179
185
  onError = _ref4.onError,
180
186
  _onVolumeChange = _ref4.onVolumeChange,
181
- onRecordComplete = _ref4.onRecordComplete;
187
+ onRecordComplete = _ref4.onRecordComplete,
188
+ debounce = _ref4.debounce;
182
189
 
183
190
  // Init worker that will do heavy calculation
184
191
  this.audioStream = stream;
185
192
  this.worker = initWorker({ onMessage: function onMessage(e) {
186
193
  switch (e.data.command) {
187
- case 'send_buffers':
188
- _this3.audioBuffer = e.data.buffers;
189
- break;
190
194
  case 'send_WAV':
191
- //const url = (window.URL || window.webkitURL).createObjectURL(e.data.audioBlob)
192
195
  onRecordComplete(e.data.audioBlob);
193
196
  break;
194
197
  }
@@ -204,7 +207,8 @@ var Recorder = function (_Component) {
204
207
  inputBuffer.push(e.inputBuffer.getChannelData(channel));
205
208
  }
206
209
  _this3.worker.postMessage({ command: 'append', timestamp: Date.now(), inputBuffer: inputBuffer });
207
- }
210
+ },
211
+ debounce: debounce
208
212
  });
209
213
 
210
214
  // Initialize hark for silence recognition
@@ -212,19 +216,19 @@ var Recorder = function (_Component) {
212
216
  stream: stream,
213
217
  onStoppedSpeaking: function onStoppedSpeaking() {
214
218
  try {
215
- _this3.worker.postMessage({ command: 'exportWAV', buffers: _this3.audioBuffer, beginning: _this3.recordStart, end: Date.now() });
216
- _this3.worker.postMessage({ command: 'clean' });
217
- _this3.audioBuffer = [];
219
+ console.log("exportWAV");
220
+ _this3.worker.postMessage({ command: 'exportWAV', beginning: _this3.recordStart, end: Date.now() });
218
221
  } catch (e) {
219
222
  onError(e);
220
223
  }
221
224
  },
222
225
  onSpeaking: function onSpeaking() {
223
- _this3.recordStart = Date.now() - INTERVAL * 3; // give it a bit of extra time
226
+ _this3.recordStart = Date.now() - debounce * 3; // give it a bit of extra time
224
227
  },
225
228
  onVolumeChange: function onVolumeChange(volume) {
226
- _onVolumeChange(volume);
227
- }
229
+ _onVolumeChange(formatVolume(volume));
230
+ },
231
+ debounce: debounce
228
232
  });
229
233
  }
230
234
  }, {
@@ -61,9 +61,16 @@ var VisualizerExample = function (_Component) {
61
61
  'div',
62
62
  null,
63
63
  _react2.default.createElement(_recorder2.default, {
64
+ debounce: 100,
64
65
  onVolumeChange: this.setVolume,
65
66
  onError: function onError(err) {
66
67
  return console.log('error', err);
68
+ },
69
+ onRecordComplete: function onRecordComplete() {
70
+ return console.log('onRecordComplete');
71
+ },
72
+ onNotAvailable: function onNotAvailable() {
73
+ return console.log('not available');
67
74
  }
68
75
  }),
69
76
  _react2.default.createElement(_Visualizer2.default, { volume: volume })
@@ -36,9 +36,10 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
36
36
  var SIMILARITY_THRESHOLD = 0.8;
37
37
  var isSpeechRecognitionAvailable = (0, _reactSpeechRecognizer.speechRecognitionAvailable)();
38
38
 
39
- var debug = function debug(wav) {
40
- //FileSaver.saveAs(wav, 'test.wav')
41
- };
39
+ /*
40
+ const debug = (wav) => {
41
+ FileSaver.saveAs(wav, 'test.wav')
42
+ }*/
42
43
 
43
44
  var sendFileToSpeechToTextApi = function sendFileToSpeechToTextApi(API_URL, wav) {
44
45
  return new Promise(function (resolve, reject) {