@checksub_team/peaks_timeline 1.4.31 → 1.4.34

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/peaks.js CHANGED
@@ -12938,16 +12938,6 @@ exports.default = _default;
12938
12938
 
12939
12939
  /**
12940
12940
  * ArrayBuffer adapter consumes binary waveform data.
12941
- * It is used as a data abstraction layer by `WaveformData`.
12942
- *
12943
- * This is supposed to be the fastest adapter ever:
12944
- * * **Pros**: working directly in memory, everything is done by reference
12945
- * (including the offsetting)
12946
- * * **Cons**: binary data are hardly readable without data format knowledge
12947
- * (and this is why this adapter exists).
12948
- *
12949
- * @param {ArrayBuffer} buffer
12950
- * @constructor
12951
12941
  */
12952
12942
 
12953
12943
  function WaveformDataArrayBufferAdapter(buffer) {
@@ -12957,19 +12947,14 @@ function WaveformDataArrayBufferAdapter(buffer) {
12957
12947
 
12958
12948
  /**
12959
12949
  * Detects if a set of data is suitable for the ArrayBuffer adapter.
12960
- * It is used internally by `WaveformData.create` so you should not bother using it.
12961
- *
12962
- * @static
12963
- * @param {Mixed} data
12964
- * @returns {boolean}
12965
12950
  */
12966
12951
 
12967
12952
  WaveformDataArrayBufferAdapter.isCompatible = function isCompatible(data) {
12968
- const isCompatible = data && typeof data === "object" && "byteLength" in data;
12953
+ var isCompatible = data && typeof data === "object" && "byteLength" in data;
12969
12954
 
12970
12955
  if (isCompatible) {
12971
- const view = new DataView(data);
12972
- const version = view.getInt32(0, true);
12956
+ var view = new DataView(data);
12957
+ var version = view.getInt32(0, true);
12973
12958
 
12974
12959
  if (version !== 1 && version !== 2) {
12975
12960
  throw new TypeError("This waveform data version not supported.");
@@ -12979,15 +12964,10 @@ WaveformDataArrayBufferAdapter.isCompatible = function isCompatible(data) {
12979
12964
  return isCompatible;
12980
12965
  };
12981
12966
 
12982
- /**
12983
- * @namespace WaveformDataArrayBufferAdapter
12984
- */
12985
-
12986
12967
  WaveformDataArrayBufferAdapter.prototype = {
12968
+
12987
12969
  /**
12988
12970
  * Returns the data format version number.
12989
- *
12990
- * @return {Integer} Version number of the consumed data format.
12991
12971
  */
12992
12972
 
12993
12973
  get version() {
@@ -13006,8 +12986,6 @@ WaveformDataArrayBufferAdapter.isCompatible = function isCompatible(data) {
13006
12986
 
13007
12987
  /**
13008
12988
  * Returns the number of channels.
13009
- *
13010
- * @return {Integer} Number of channels.
13011
12989
  */
13012
12990
 
13013
12991
  get channels() {
@@ -13021,8 +12999,6 @@ WaveformDataArrayBufferAdapter.isCompatible = function isCompatible(data) {
13021
12999
 
13022
13000
  /**
13023
13001
  * Returns the number of samples per second.
13024
- *
13025
- * @return {Integer} Number of samples per second.
13026
13002
  */
13027
13003
 
13028
13004
  get sample_rate() {
@@ -13031,8 +13007,6 @@ WaveformDataArrayBufferAdapter.isCompatible = function isCompatible(data) {
13031
13007
 
13032
13008
  /**
13033
13009
  * Returns the scale (number of samples per pixel).
13034
- *
13035
- * @return {Integer} Number of samples per pixel.
13036
13010
  */
13037
13011
 
13038
13012
  get scale() {
@@ -13041,8 +13015,6 @@ WaveformDataArrayBufferAdapter.isCompatible = function isCompatible(data) {
13041
13015
 
13042
13016
  /**
13043
13017
  * Returns the length of the waveform data (number of data points).
13044
- *
13045
- * @return {Integer} Length of the waveform data.
13046
13018
  */
13047
13019
 
13048
13020
  get length() {
@@ -13050,10 +13022,7 @@ WaveformDataArrayBufferAdapter.isCompatible = function isCompatible(data) {
13050
13022
  },
13051
13023
 
13052
13024
  /**
13053
- * Returns a value at a specific offset.
13054
- *
13055
- * @param {Integer} index
13056
- * @return {Integer} waveform value
13025
+ * Returns a waveform data value at a specific offset.
13057
13026
  */
13058
13027
 
13059
13028
  at: function at_sample(index) {
@@ -13063,9 +13032,6 @@ WaveformDataArrayBufferAdapter.isCompatible = function isCompatible(data) {
13063
13032
  /**
13064
13033
  * Returns a new ArrayBuffer with the concatenated waveform.
13065
13034
  * All waveforms must have identical metadata (version, channels, etc)
13066
- *
13067
- * @param {...WaveformDataArrayBufferAdapter} otherAdapters One or more adapters to concatenate
13068
- * @return {ArrayBuffer} concatenated ArrayBuffer
13069
13035
  */
13070
13036
 
13071
13037
  concatBuffers: function() {
@@ -13155,10 +13121,9 @@ WaveformDataObjectAdapter.isCompatible = function isCompatible(data) {
13155
13121
  */
13156
13122
 
13157
13123
  WaveformDataObjectAdapter.prototype = {
13124
+
13158
13125
  /**
13159
13126
  * Returns the data format version number.
13160
- *
13161
- * @return {Integer} Version number of the consumed data format.
13162
13127
  */
13163
13128
 
13164
13129
  get version() {
@@ -13175,8 +13140,6 @@ WaveformDataObjectAdapter.prototype = {
13175
13140
 
13176
13141
  /**
13177
13142
  * Returns the number of channels.
13178
- *
13179
- * @return {Integer} Number of channels.
13180
13143
  */
13181
13144
 
13182
13145
  get channels() {
@@ -13185,8 +13148,6 @@ WaveformDataObjectAdapter.prototype = {
13185
13148
 
13186
13149
  /**
13187
13150
  * Returns the number of samples per second.
13188
- *
13189
- * @return {Integer} Number of samples per second.
13190
13151
  */
13191
13152
 
13192
13153
  get sample_rate() {
@@ -13195,8 +13156,6 @@ WaveformDataObjectAdapter.prototype = {
13195
13156
 
13196
13157
  /**
13197
13158
  * Returns the scale (number of samples per pixel).
13198
- *
13199
- * @return {Integer} Number of samples per pixel.
13200
13159
  */
13201
13160
 
13202
13161
  get scale() {
@@ -13205,8 +13164,6 @@ WaveformDataObjectAdapter.prototype = {
13205
13164
 
13206
13165
  /**
13207
13166
  * Returns the length of the waveform data (number of data points).
13208
- *
13209
- * @return {Integer} Length of the waveform data.
13210
13167
  */
13211
13168
 
13212
13169
  get length() {
@@ -13214,14 +13171,11 @@ WaveformDataObjectAdapter.prototype = {
13214
13171
  },
13215
13172
 
13216
13173
  /**
13217
- * Returns a value at a specific offset.
13218
- *
13219
- * @param {Integer} index
13220
- * @return {number} waveform value
13174
+ * Returns a waveform data value at a specific offset.
13221
13175
  */
13222
13176
 
13223
13177
  at: function at_sample(index) {
13224
- const data = this._data.data;
13178
+ var data = this._data.data;
13225
13179
 
13226
13180
  if (index >= 0 && index < data.length) {
13227
13181
  return data[index];
@@ -13234,9 +13188,6 @@ WaveformDataObjectAdapter.prototype = {
13234
13188
  /**
13235
13189
  * Returns a new data object with the concatenated waveform.
13236
13190
  * Both waveforms must have identical metadata (version, channels, etc)
13237
- *
13238
- * @param {...WaveformDataObjectAdapter} otherAdapters One or more adapters
13239
- * @return {Mixed} combined waveform data
13240
13191
  */
13241
13192
 
13242
13193
  concatBuffers: function() {
@@ -13261,165 +13212,166 @@ module.exports = WaveformDataObjectAdapter;
13261
13212
 
13262
13213
  var WaveformData = _dereq_("../core");
13263
13214
  var InlineWorker = _dereq_("inline-worker");
13215
+ var MainThreadWorker = _dereq_("../util/main-thread-worker");
13264
13216
 
13265
- /**
13266
- * This callback is executed once the audio has been decoded by the browser and
13267
- * resampled by waveform-data.
13268
- *
13269
- * @callback onAudioResampled
13270
- * @param {Error?}
13271
- * @param {WaveformData} waveform_data Waveform instance of the browser decoded audio
13272
- * @param {AudioBuffer} audio_buffer Decoded audio buffer
13273
- */
13274
-
13275
- /**
13276
- * AudioBuffer-based WaveformData generator
13277
- *
13278
- * Adapted from BlockFile::CalcSummary in Audacity, with permission.
13279
- * @see https://code.google.com/p/audacity/source/browse/audacity-src/trunk/src/BlockFile.cpp
13280
- *
13281
- * @param {Object.<{scale: Number, amplitude_scale: Number, split_channels: Boolean}>} options
13282
- * @param {onAudioResampled} callback
13283
- * @returns {Function.<AudioBuffer>}
13284
- */
13285
-
13286
- function getAudioDecoder(options, callback) {
13287
- return function onAudioDecoded(audio_buffer) {
13288
- var worker = new InlineWorker(function() {
13289
- var INT8_MAX = 127;
13290
- var INT8_MIN = -128;
13217
+ function processWorker(workerArgs, callback) {
13218
+ var WaveformWorker = workerArgs.disable_worker ? MainThreadWorker : InlineWorker;
13291
13219
 
13292
- function calculateWaveformDataLength(audio_sample_count, scale) {
13293
- var data_length = Math.floor(audio_sample_count / scale);
13220
+ var worker = new WaveformWorker(function() {
13221
+ var INT8_MAX = 127;
13222
+ var INT8_MIN = -128;
13294
13223
 
13295
- var samples_remaining = audio_sample_count - (data_length * scale);
13224
+ function calculateWaveformDataLength(audio_sample_count, scale) {
13225
+ var data_length = Math.floor(audio_sample_count / scale);
13296
13226
 
13297
- if (samples_remaining > 0) {
13298
- data_length++;
13299
- }
13227
+ var samples_remaining = audio_sample_count - (data_length * scale);
13300
13228
 
13301
- return data_length;
13229
+ if (samples_remaining > 0) {
13230
+ data_length++;
13302
13231
  }
13303
13232
 
13304
- this.addEventListener("message", function(evt) {
13305
- var scale = evt.data.scale;
13306
- var amplitude_scale = evt.data.amplitude_scale;
13307
- var split_channels = evt.data.split_channels;
13308
- var audio_buffer = evt.data.audio_buffer;
13309
-
13310
- var channels = audio_buffer.channels;
13311
- var output_channels = split_channels ? channels.length : 1;
13312
- var version = output_channels === 1 ? 1 : 2;
13313
- var header_size = version === 1 ? 20 : 24;
13314
- var data_length = calculateWaveformDataLength(audio_buffer.length, scale);
13315
- var total_size = header_size + data_length * 2 * output_channels;
13316
- var data_object = new DataView(new ArrayBuffer(total_size));
13317
-
13318
- var min_value = new Array(output_channels);
13319
- var max_value = new Array(output_channels);
13233
+ return data_length;
13234
+ }
13320
13235
 
13321
- for (let channel = 0; channel < output_channels; channel++) {
13322
- min_value[channel] = Infinity;
13323
- max_value[channel] = -Infinity;
13324
- }
13236
+ this.addEventListener("message", function listener(evt) {
13237
+ if (!evt.data.audio_buffer) {
13238
+ return;
13239
+ }
13325
13240
 
13326
- var scale_counter = 0;
13327
- var buffer_length = audio_buffer.length;
13328
- var offset = header_size;
13329
- var channel, i;
13241
+ var scale = evt.data.scale;
13242
+ var amplitude_scale = evt.data.amplitude_scale;
13243
+ var split_channels = evt.data.split_channels;
13244
+ var audio_buffer = evt.data.audio_buffer;
13245
+
13246
+ var channels = audio_buffer.channels;
13247
+ var output_channels = split_channels ? channels.length : 1;
13248
+ var version = output_channels === 1 ? 1 : 2;
13249
+ var header_size = version === 1 ? 20 : 24;
13250
+ var data_length = calculateWaveformDataLength(audio_buffer.length, scale);
13251
+ var total_size = header_size + data_length * 2 * output_channels;
13252
+ var data_object = new DataView(new ArrayBuffer(total_size));
13253
+
13254
+ var scale_counter = 0;
13255
+ var buffer_length = audio_buffer.length;
13256
+ var offset = header_size;
13257
+ var channel, i;
13258
+
13259
+ var min_value = new Array(output_channels);
13260
+ var max_value = new Array(output_channels);
13261
+
13262
+ for (channel = 0; channel < output_channels; channel++) {
13263
+ min_value[channel] = Infinity;
13264
+ max_value[channel] = -Infinity;
13265
+ }
13330
13266
 
13331
- data_object.setInt32(0, version, true); // Version
13332
- data_object.setUint32(4, 1, true); // Is 8 bit?
13333
- data_object.setInt32(8, audio_buffer.sampleRate, true); // Sample rate
13334
- data_object.setInt32(12, scale, true); // Scale
13335
- data_object.setInt32(16, data_length, true); // Length
13267
+ data_object.setInt32(0, version, true); // Version
13268
+ data_object.setUint32(4, 1, true); // Is 8 bit?
13269
+ data_object.setInt32(8, audio_buffer.sampleRate, true); // Sample rate
13270
+ data_object.setInt32(12, scale, true); // Scale
13271
+ data_object.setInt32(16, data_length, true); // Length
13336
13272
 
13337
- if (version === 2) {
13338
- data_object.setInt32(20, output_channels, true);
13339
- }
13273
+ if (version === 2) {
13274
+ data_object.setInt32(20, output_channels, true);
13275
+ }
13340
13276
 
13341
- for (i = 0; i < buffer_length; i++) {
13342
- var sample = 0;
13277
+ for (i = 0; i < buffer_length; i++) {
13278
+ var sample = 0;
13343
13279
 
13344
- if (output_channels === 1) {
13345
- for (channel = 0; channel < channels.length; ++channel) {
13346
- sample += channels[channel][i];
13347
- }
13280
+ if (output_channels === 1) {
13281
+ for (channel = 0; channel < channels.length; ++channel) {
13282
+ sample += channels[channel][i];
13283
+ }
13348
13284
 
13349
- sample = Math.floor(INT8_MAX * sample * amplitude_scale / channels.length);
13285
+ sample = Math.floor(INT8_MAX * sample * amplitude_scale / channels.length);
13350
13286
 
13351
- if (sample < min_value[0]) {
13352
- min_value[0] = sample;
13287
+ if (sample < min_value[0]) {
13288
+ min_value[0] = sample;
13353
13289
 
13354
- if (min_value[0] < INT8_MIN) {
13355
- min_value[0] = INT8_MIN;
13356
- }
13290
+ if (min_value[0] < INT8_MIN) {
13291
+ min_value[0] = INT8_MIN;
13357
13292
  }
13293
+ }
13358
13294
 
13359
- if (sample > max_value[0]) {
13360
- max_value[0] = sample;
13295
+ if (sample > max_value[0]) {
13296
+ max_value[0] = sample;
13361
13297
 
13362
- if (max_value[0] > INT8_MAX) {
13363
- max_value[0] = INT8_MAX;
13364
- }
13298
+ if (max_value[0] > INT8_MAX) {
13299
+ max_value[0] = INT8_MAX;
13365
13300
  }
13366
13301
  }
13367
- else {
13368
- for (channel = 0; channel < output_channels; ++channel) {
13369
- sample = Math.floor(INT8_MAX * channels[channel][i] * amplitude_scale);
13370
-
13371
- if (sample < min_value[channel]) {
13372
- min_value[channel] = sample;
13373
-
13374
- if (min_value[channel] < INT8_MIN) {
13375
- min_value[channel] = INT8_MIN;
13376
- }
13377
- }
13302
+ }
13303
+ else {
13304
+ for (channel = 0; channel < output_channels; ++channel) {
13305
+ sample = Math.floor(INT8_MAX * channels[channel][i] * amplitude_scale);
13378
13306
 
13379
- if (sample > max_value[channel]) {
13380
- max_value[channel] = sample;
13307
+ if (sample < min_value[channel]) {
13308
+ min_value[channel] = sample;
13381
13309
 
13382
- if (max_value[channel] > INT8_MAX) {
13383
- max_value[channel] = INT8_MAX;
13384
- }
13310
+ if (min_value[channel] < INT8_MIN) {
13311
+ min_value[channel] = INT8_MIN;
13385
13312
  }
13386
13313
  }
13387
- }
13388
13314
 
13389
- if (++scale_counter === scale) {
13390
- for (channel = 0; channel < output_channels; channel++) {
13391
- data_object.setInt8(offset++, min_value[channel]);
13392
- data_object.setInt8(offset++, max_value[channel]);
13315
+ if (sample > max_value[channel]) {
13316
+ max_value[channel] = sample;
13393
13317
 
13394
- min_value[channel] = Infinity;
13395
- max_value[channel] = -Infinity;
13318
+ if (max_value[channel] > INT8_MAX) {
13319
+ max_value[channel] = INT8_MAX;
13320
+ }
13396
13321
  }
13397
-
13398
- scale_counter = 0;
13399
13322
  }
13400
13323
  }
13401
13324
 
13402
- if (scale_counter > 0) {
13325
+ if (++scale_counter === scale) {
13403
13326
  for (channel = 0; channel < output_channels; channel++) {
13404
13327
  data_object.setInt8(offset++, min_value[channel]);
13405
13328
  data_object.setInt8(offset++, max_value[channel]);
13329
+
13330
+ min_value[channel] = Infinity;
13331
+ max_value[channel] = -Infinity;
13406
13332
  }
13333
+
13334
+ scale_counter = 0;
13407
13335
  }
13336
+ }
13408
13337
 
13409
- this.postMessage(data_object);
13410
- });
13338
+ if (scale_counter > 0) {
13339
+ for (channel = 0; channel < output_channels; channel++) {
13340
+ data_object.setInt8(offset++, min_value[channel]);
13341
+ data_object.setInt8(offset++, max_value[channel]);
13342
+ }
13343
+ }
13344
+
13345
+ this.postMessage(data_object);
13346
+ this.removeEventListener("message", listener);
13347
+ this.close();
13411
13348
  });
13349
+ });
13412
13350
 
13413
- worker.addEventListener("message", function(evt) {
13414
- var data_object = evt.data;
13351
+ worker.addEventListener("message", function listener(evt) {
13352
+ if (evt.data.audio_buffer) {
13353
+ return;
13354
+ }
13415
13355
 
13416
- callback(
13417
- null,
13418
- new WaveformData(data_object.buffer),
13419
- audio_buffer
13420
- );
13421
- });
13356
+ callback(evt.data);
13357
+
13358
+ // We're only sending a single message to each listener, so
13359
+ // remove the callback afterwards to avoid leaks.
13360
+ worker.removeEventListener("message", listener);
13361
+ });
13422
13362
 
13363
+ worker.postMessage(workerArgs);
13364
+ }
13365
+
13366
+ /**
13367
+ * AudioBuffer-based WaveformData generator
13368
+ *
13369
+ * Adapted from BlockFile::CalcSummary in Audacity, with permission.
13370
+ * See https://code.google.com/p/audacity/source/browse/audacity-src/trunk/src/BlockFile.cpp
13371
+ */
13372
+
13373
+ function getAudioDecoder(options, callback) {
13374
+ return function onAudioDecoded(audio_buffer) {
13423
13375
  // Construct a simple object with the necessary AudioBuffer data,
13424
13376
  // as we cannot send an AudioBuffer to a Web Worker.
13425
13377
  var audio_buffer_obj = {
@@ -13433,35 +13385,38 @@ function getAudioDecoder(options, callback) {
13433
13385
  audio_buffer_obj.channels[channel] = audio_buffer.getChannelData(channel);
13434
13386
  }
13435
13387
 
13436
- worker.postMessage({
13388
+ var worker_args = {
13437
13389
  scale: options.scale,
13438
13390
  amplitude_scale: options.amplitude_scale,
13439
13391
  split_channels: options.split_channels,
13440
- audio_buffer: audio_buffer_obj
13392
+ audio_buffer: audio_buffer_obj,
13393
+ disable_worker: options.disable_worker
13394
+ };
13395
+
13396
+ processWorker(worker_args, function(data_object) {
13397
+ callback(null, new WaveformData(data_object.buffer), audio_buffer);
13441
13398
  });
13442
13399
  };
13443
13400
  }
13444
13401
 
13445
13402
  module.exports = getAudioDecoder;
13446
13403
 
13447
- },{"../core":83,"inline-worker":3}],80:[function(_dereq_,module,exports){
13404
+ },{"../core":83,"../util/main-thread-worker":84,"inline-worker":3}],80:[function(_dereq_,module,exports){
13448
13405
  "use strict";
13449
13406
 
13450
13407
  var defaultOptions = {
13451
13408
  scale: 512,
13452
13409
  amplitude_scale: 1.0,
13453
- split_channels: false
13410
+ split_channels: false,
13411
+ disable_worker: false
13454
13412
  };
13455
13413
 
13456
13414
  function getOptions(options) {
13457
- if (Object.prototype.hasOwnProperty.call(options, "scale_adjuster")) {
13458
- throw new Error("Please rename the 'scale_adjuster' option to 'amplitude_scale'");
13459
- }
13460
-
13461
13415
  var opts = {
13462
13416
  scale: options.scale || defaultOptions.scale,
13463
13417
  amplitude_scale: options.amplitude_scale || defaultOptions.amplitude_scale,
13464
- split_channels: options.split_channels || defaultOptions.split_channels
13418
+ split_channels: options.split_channels || defaultOptions.split_channels,
13419
+ disable_worker: options.disable_worker || defaultOptions.disable_worker
13465
13420
  };
13466
13421
 
13467
13422
  return opts;
@@ -13503,39 +13458,7 @@ function createFromAudioBuffer(audioBuffer, options, callback) {
13503
13458
  }
13504
13459
 
13505
13460
  /**
13506
- * Creates a working WaveformData based on binary audio data.
13507
- *
13508
- * This is still quite experimental and the result will mostly depend on the
13509
- * level of browser support.
13510
- *
13511
- * ```javascript
13512
- * const xhr = new XMLHttpRequest();
13513
- * const audioContext = new AudioContext();
13514
- *
13515
- * // URL of a CORS MP3/Ogg file
13516
- * xhr.open('GET', 'https://example.com/audio/track.ogg');
13517
- * xhr.responseType = 'arraybuffer';
13518
- *
13519
- * xhr.addEventListener('load', function(progressEvent) {
13520
- * WaveformData.createFromAudio(audioContext, progressEvent.target.response,
13521
- * function(err, waveform) {
13522
- * if (err) {
13523
- * console.error(err);
13524
- * return;
13525
- * }
13526
- *
13527
- * console.log(waveform.duration);
13528
- * });
13529
- * });
13530
- *
13531
- * xhr.send();
13532
- * ```
13533
- *
13534
- * @todo Use `SourceBuffer.appendBuffer` and `ProgressEvent` to stream the decoding?
13535
- * @param {AudioContext|webkitAudioContext} audio_context
13536
- * @param {ArrayBuffer} audio_data
13537
- * @param {callback} what to do once the decoding is done
13538
- * @constructor
13461
+ * Creates a WaveformData instance from audio.
13539
13462
  */
13540
13463
 
13541
13464
  function createFromAudio(options, callback) {
@@ -13548,7 +13471,10 @@ function createFromAudio(options, callback) {
13548
13471
  return createFromAudioBuffer(options.audio_buffer, opts, callback);
13549
13472
  }
13550
13473
  else {
13551
- throw new TypeError("Please pass either an AudioContext and ArrayBuffer, or an AudioBuffer object");
13474
+ throw new TypeError(
13475
+ // eslint-disable-next-line
13476
+ "WaveformData.createFromAudio(): Pass either an AudioContext and ArrayBuffer, or an AudioBuffer object"
13477
+ );
13552
13478
  }
13553
13479
  }
13554
13480
 
@@ -13559,10 +13485,6 @@ module.exports = createFromAudio;
13559
13485
 
13560
13486
  /**
13561
13487
  * Provides access to the waveform data for a single audio channel.
13562
- *
13563
- * @param {WaveformData} waveformData Waveform data.
13564
- * @param {Number} channelIndex Channel number.
13565
- * @constructor
13566
13488
  */
13567
13489
 
13568
13490
  function WaveformDataChannel(waveformData, channelIndex) {
@@ -13571,58 +13493,27 @@ function WaveformDataChannel(waveformData, channelIndex) {
13571
13493
  }
13572
13494
 
13573
13495
  /**
13574
- * Returns a min value for a specific offset.
13575
- *
13576
- * ```javascript
13577
- * var waveform = WaveformData.create({ ... });
13578
- * var channel = waveform.channel(0);
13579
- *
13580
- * console.log(channel.min_sample(10)); // -> -12
13581
- * ```
13582
- *
13583
- * @api
13584
- * @param {Integer} offset
13585
- * @return {Number} Offset min value
13496
+ * Returns the waveform minimum at the given index position.
13586
13497
  */
13587
13498
 
13588
13499
  WaveformDataChannel.prototype.min_sample = function(index) {
13589
- const offset = (index * this._waveformData.channels + this._channelIndex) * 2;
13500
+ var offset = (index * this._waveformData.channels + this._channelIndex) * 2;
13590
13501
 
13591
13502
  return this._waveformData._adapter.at(offset);
13592
13503
  };
13593
13504
 
13594
13505
  /**
13595
- * Returns a max value for a specific offset.
13596
- *
13597
- * ```javascript
13598
- * var waveform = WaveformData.create({ ... });
13599
- * var channel = waveform.channel(0);
13600
- *
13601
- * console.log(channel.max_sample(10)); // -> 12
13602
- * ```
13603
- *
13604
- * @api
13605
- * @param {Integer} offset
13606
- * @return {Number} Offset max value
13506
+ * Returns the waveform maximum at the given index position.
13607
13507
  */
13608
13508
 
13609
13509
  WaveformDataChannel.prototype.max_sample = function(index) {
13610
- const offset = (index * this._waveformData.channels + this._channelIndex) * 2 + 1;
13510
+ var offset = (index * this._waveformData.channels + this._channelIndex) * 2 + 1;
13611
13511
 
13612
13512
  return this._waveformData._adapter.at(offset);
13613
13513
  };
13614
13514
 
13615
13515
  /**
13616
- * Returns all the min values within the current offset.
13617
- *
13618
- * ```javascript
13619
- * var waveform = WaveformData.create({ ... });
13620
- * var channel = waveform.channel(0);
13621
- *
13622
- * console.log(channel.min_array()); // -> [-7, -5, -10]
13623
- * ```
13624
- *
13625
- * @return {Array.<Integer>} Min values contained in the offset.
13516
+ * Returns all the waveform minimum values as an array.
13626
13517
  */
13627
13518
 
13628
13519
  WaveformDataChannel.prototype.min_array = function() {
@@ -13634,16 +13525,7 @@ WaveformDataChannel.prototype.min_array = function() {
13634
13525
  };
13635
13526
 
13636
13527
  /**
13637
- * Returns all the max values within the current offset.
13638
- *
13639
- * ```javascript
13640
- * var waveform = WaveformData.create({ ... });
13641
- * var channel = waveform.channel(0);
13642
- *
13643
- * console.log(channel.max_array()); // -> [9, 6, 11]
13644
- * ```
13645
- *
13646
- * @return {Array.<Integer>} Max values contained in the offset.
13528
+ * Returns all the waveform maximum values as an array.
13647
13529
  */
13648
13530
 
13649
13531
  WaveformDataChannel.prototype.max_array = function() {
@@ -13669,32 +13551,7 @@ var adapters = [
13669
13551
  ];
13670
13552
 
13671
13553
  /**
13672
- * Facade to iterate on audio waveform response.
13673
- *
13674
- * ```javascript
13675
- * var waveform = new WaveformData({ ... });
13676
- *
13677
- * var json_waveform = new WaveformData(xhr.responseText);
13678
- *
13679
- * var arraybuff_waveform = new WaveformData(
13680
- * getArrayBufferData()
13681
- * );
13682
- * ```
13683
- *
13684
- * ## Offsets
13685
- *
13686
- * An **offset** is a non-destructive way to iterate on a subset of data.
13687
- *
13688
- * It is the easiest way to **navigate** through data without having to deal
13689
- * with complex calculations. Simply iterate over the data to display them.
13690
- *
13691
- * *Notice*: the default offset is the entire set of data.
13692
- *
13693
- * @param {String|ArrayBuffer|Object} data Waveform data,
13694
- * to be consumed by the related adapter.
13695
- * @param {WaveformData.adapter|Function} adapter Backend adapter used to manage
13696
- * access to the data.
13697
- * @constructor
13554
+ * Provides access to waveform data.
13698
13555
  */
13699
13556
 
13700
13557
  function WaveformData(data) {
@@ -13704,45 +13561,19 @@ function WaveformData(data) {
13704
13561
 
13705
13562
  this._channels = [];
13706
13563
 
13707
- for (let channel = 0; channel < this.channels; channel++) {
13564
+ for (var channel = 0; channel < this.channels; channel++) {
13708
13565
  this._channels[channel] = new WaveformDataChannel(this, channel);
13709
13566
  }
13710
13567
  }
13711
13568
 
13712
13569
  /**
13713
- * Creates an instance of WaveformData by guessing the adapter from the
13714
- * data type. It can also accept an XMLHttpRequest response.
13715
- *
13716
- * ```javascript
13717
- * var xhr = new XMLHttpRequest();
13718
- * xhr.open("GET", "http://example.com/waveforms/track.dat");
13719
- * xhr.responseType = "arraybuffer";
13720
- *
13721
- * xhr.addEventListener("load", function onResponse(progressEvent) {
13722
- * var waveform = WaveformData.create(progressEvent.target);
13723
- *
13724
- * console.log(waveform.duration);
13725
- * });
13726
- *
13727
- * xhr.send();
13728
- * ```
13729
- *
13730
- * @static
13731
- * @throws TypeError
13732
- * @param {Object} data
13733
- * @return {WaveformData}
13570
+ * Creates and returns a WaveformData instance from the given waveform data.
13734
13571
  */
13735
13572
 
13736
13573
  WaveformData.create = function create(data) {
13737
13574
  return new WaveformData(data);
13738
13575
  };
13739
13576
 
13740
- /**
13741
- * Public API for the Waveform Data manager.
13742
- *
13743
- * @namespace WaveformData
13744
- */
13745
-
13746
13577
  WaveformData.prototype = {
13747
13578
 
13748
13579
  _getAdapter: function(data) {
@@ -13756,47 +13587,23 @@ WaveformData.prototype = {
13756
13587
  });
13757
13588
 
13758
13589
  if (Adapter === null) {
13759
- throw new TypeError("Could not detect a WaveformData adapter from the input.");
13590
+ throw new TypeError(
13591
+ "WaveformData.create(): Could not detect a WaveformData adapter from the input"
13592
+ );
13760
13593
  }
13761
13594
 
13762
13595
  return Adapter;
13763
13596
  },
13764
13597
 
13765
13598
  /**
13766
- * Creates a new WaveformData object with resampled data.
13767
- * Returns a rescaled waveform, to either fit the waveform to a specific
13768
- * width, or to a specific zoom level.
13769
- *
13770
- * **Note**: You may specify either the *width* or the *scale*, but not both.
13771
- * The `scale` will be deduced from the `width` you want to fit the data into.
13599
+ * Creates and returns a new WaveformData object with resampled data.
13600
+ * Use this method to create waveform data at different zoom levels.
13772
13601
  *
13773
13602
  * Adapted from Sequence::GetWaveDisplay in Audacity, with permission.
13774
- *
13775
- * ```javascript
13776
- * var waveform = WaveformData.create({ ... });
13777
- * // ...
13778
- *
13779
- * // fitting the data in a 500px wide canvas
13780
- * var resampled_waveform = waveform.resample({ width: 500 });
13781
- *
13782
- * console.log(resampled_waveform.min.length); // -> 500
13783
- *
13784
- * // zooming out on a 3 times less precise scale
13785
- * var resampled_waveform = waveform.resample({ scale: waveform.scale * 3 });
13786
- * ```
13787
- *
13788
- * @see https://code.google.com/p/audacity/source/browse/audacity-src/trunk/src/Sequence.cpp
13789
- * @param {Number|{width: Number, scale: Number}} options Either a constraint width or a constraint sample rate
13790
- * @return {WaveformData} New resampled object
13603
+ * https://code.google.com/p/audacity/source/browse/audacity-src/trunk/src/Sequence.cpp
13791
13604
  */
13792
13605
 
13793
13606
  resample: function(options) {
13794
- if (typeof options === "number") {
13795
- options = {
13796
- width: options
13797
- };
13798
- }
13799
-
13800
13607
  options.input_index = typeof options.input_index === "number" ? options.input_index : null;
13801
13608
  options.output_index = typeof options.output_index === "number" ? options.output_index : null;
13802
13609
  options.scale = typeof options.scale === "number" ? options.scale : null;
@@ -13805,48 +13612,63 @@ WaveformData.prototype = {
13805
13612
  var is_partial_resampling = Boolean(options.input_index) || Boolean(options.output_index);
13806
13613
 
13807
13614
  if (options.input_index != null && (options.input_index < 0)) {
13808
- throw new RangeError("options.input_index should be a positive integer value. [" + options.input_index + "]");
13615
+ throw new RangeError(
13616
+ "WaveformData.resample(): input_index should be a positive integer value"
13617
+ );
13809
13618
  }
13810
13619
 
13811
13620
  if (options.output_index != null && (options.output_index < 0)) {
13812
- throw new RangeError("options.output_index should be a positive integer value. [" + options.output_index + "]");
13621
+ throw new RangeError(
13622
+ "WaveformData.resample(): output_index should be a positive integer value"
13623
+ );
13813
13624
  }
13814
13625
 
13815
13626
  if (options.width != null && (options.width <= 0)) {
13816
- throw new RangeError("options.width should be a strictly positive integer value. [" + options.width + "]");
13627
+ throw new RangeError("WaveformData.resample(): width should be a positive integer value");
13817
13628
  }
13818
13629
 
13819
13630
  if (options.scale != null && (options.scale <= 0)) {
13820
- throw new RangeError("options.scale should be a strictly positive integer value. [" + options.scale + "]");
13631
+ throw new RangeError("WaveformData.resample(): scale should be a positive integer value");
13821
13632
  }
13822
13633
 
13823
13634
  if (!options.scale && !options.width) {
13824
- throw new RangeError("You should provide either a resampling scale or a width in pixel the data should fit in.");
13635
+ throw new Error("WaveformData.resample(): Missing scale or width option");
13825
13636
  }
13826
13637
 
13827
- var definedPartialOptionsCount = ["width", "scale", "output_index", "input_index"].reduce(function(count, key) {
13828
- return count + (options[key] === null ? 0 : 1);
13829
- }, 0);
13830
-
13831
- if (is_partial_resampling && definedPartialOptionsCount !== 4) {
13832
- throw new Error("Some partial resampling options are missing. You provided " + definedPartialOptionsCount + " of them over 4.");
13638
+ if (is_partial_resampling) {
13639
+ if (options.width === null ||
13640
+ options.scale === null ||
13641
+ options.input_index === null ||
13642
+ options.output_index === null) {
13643
+ throw new Error(
13644
+ "WaveformData.resample(): Missing width, scale, input_index, or output_index option"
13645
+ );
13646
+ }
13833
13647
  }
13834
13648
 
13835
13649
  var output_data = [];
13836
- var samples_per_pixel = options.scale || Math.floor(this.duration * this.sample_rate / options.width); // scale we want to reach
13650
+ // Scale we want to reach
13651
+ var samples_per_pixel = options.scale ||
13652
+ Math.floor(this.duration * this.sample_rate / options.width);
13837
13653
  var scale = this.scale; // scale we are coming from
13838
13654
  var channel_count = 2 * this.channels;
13839
13655
 
13840
- var input_buffer_size = this.length; // the amount of data we want to resample i.e. final zoom want to resample all data but for intermediate zoom we want to resample subset
13841
- var input_index = options.input_index || 0; // is this start point? or is this the index at current scale
13842
- var output_index = options.output_index || 0; // is this end point? or is this the index at scale we want to be?
13656
+ // The amount of data we want to resample i.e. final zoom want to resample
13657
+ // all data but for intermediate zoom we want to resample subset
13658
+ var input_buffer_size = this.length;
13659
+ // Is this start point? or is this the index at current scale?
13660
+ var input_index = options.input_index || 0;
13661
+ // Is this end point? or is this the index at scale we want to be?
13662
+ var output_index = options.output_index || 0;
13843
13663
 
13844
13664
  var channels = this.channels;
13845
13665
 
13846
13666
  var min = new Array(channels);
13847
13667
  var max = new Array(channels);
13848
13668
 
13849
- for (let channel = 0; channel < channels; ++channel) {
13669
+ var channel;
13670
+
13671
+ for (channel = 0; channel < channels; ++channel) {
13850
13672
  if (input_buffer_size > 0) {
13851
13673
  min[channel] = this.channel(channel).min_sample(input_index);
13852
13674
  max[channel] = this.channel(channel).max_sample(input_index);
@@ -13861,7 +13683,9 @@ WaveformData.prototype = {
13861
13683
  var max_value = 127;
13862
13684
 
13863
13685
  if (samples_per_pixel < scale) {
13864
- throw new Error("Zoom level " + samples_per_pixel + " too low, minimum: " + scale);
13686
+ throw new Error(
13687
+ "WaveformData.resample(): Zoom level " + samples_per_pixel + " too low, minimum: " + scale
13688
+ );
13865
13689
  }
13866
13690
 
13867
13691
  var where, prev_where, stop, value, last_input_index;
@@ -13870,15 +13694,11 @@ WaveformData.prototype = {
13870
13694
  return Math.floor(x * samples_per_pixel);
13871
13695
  }
13872
13696
 
13873
- function add_sample(min, max) {
13874
- output_data.push(min, max);
13875
- }
13876
-
13877
13697
  while (input_index < input_buffer_size) {
13878
13698
  while (Math.floor(sample_at_pixel(output_index) / scale) <= input_index) {
13879
13699
  if (output_index > 0) {
13880
- for (let channel = 0; channel < channels; ++channel) {
13881
- add_sample(min[channel], max[channel]);
13700
+ for (channel = 0; channel < channels; ++channel) {
13701
+ output_data.push(min[channel], max[channel]);
13882
13702
  }
13883
13703
  }
13884
13704
 
@@ -13890,7 +13710,7 @@ WaveformData.prototype = {
13890
13710
  prev_where = sample_at_pixel(output_index - 1);
13891
13711
 
13892
13712
  if (where !== prev_where) {
13893
- for (let channel = 0; channel < channels; ++channel) {
13713
+ for (channel = 0; channel < channels; ++channel) {
13894
13714
  min[channel] = max_value;
13895
13715
  max[channel] = min_value;
13896
13716
  }
@@ -13905,7 +13725,7 @@ WaveformData.prototype = {
13905
13725
  }
13906
13726
 
13907
13727
  while (input_index < stop) {
13908
- for (let channel = 0; channel < channels; ++channel) {
13728
+ for (channel = 0; channel < channels; ++channel) {
13909
13729
  value = this.channel(channel).min_sample(input_index);
13910
13730
 
13911
13731
  if (value < min[channel]) {
@@ -13930,14 +13750,14 @@ WaveformData.prototype = {
13930
13750
  if (is_partial_resampling) {
13931
13751
  if ((output_data.length / channel_count) > options.width &&
13932
13752
  input_index !== last_input_index) {
13933
- for (let channel = 0; channel < channels; ++channel) {
13934
- add_sample(min[channel], max[channel]);
13753
+ for (channel = 0; channel < channels; ++channel) {
13754
+ output_data.push(min[channel], max[channel]);
13935
13755
  }
13936
13756
  }
13937
13757
  }
13938
13758
  else if (input_index !== last_input_index) {
13939
- for (let channel = 0; channel < channels; ++channel) {
13940
- add_sample(min[channel], max[channel]);
13759
+ for (channel = 0; channel < channels; ++channel) {
13760
+ output_data.push(min[channel], max[channel]);
13941
13761
  }
13942
13762
  }
13943
13763
 
@@ -13953,11 +13773,9 @@ WaveformData.prototype = {
13953
13773
  },
13954
13774
 
13955
13775
  /**
13956
- * Return a new WaveformData instance with the concatenated result of multiple waveforms.
13957
- *
13958
- * @param {...WaveformData} otherWaveforms One or more waveform instances to concatenate
13959
- * @return {WaveformData} New concatenated object
13776
+ * Concatenates with one or more other waveforms, returning a new WaveformData object.
13960
13777
  */
13778
+
13961
13779
  concat: function() {
13962
13780
  var self = this;
13963
13781
  var otherWaveforms = Array.prototype.slice.call(arguments);
@@ -13969,7 +13787,7 @@ WaveformData.prototype = {
13969
13787
  self.scale !== otherWaveform.scale ||
13970
13788
  Object.getPrototypeOf(self._adapter) !== Object.getPrototypeOf(otherWaveform._adapter) ||
13971
13789
  self._adapter.version !== otherWaveform._adapter.version) {
13972
- throw new Error("Waveforms are incompatible");
13790
+ throw new Error("WaveformData.concat(): Waveforms are incompatible");
13973
13791
  }
13974
13792
  });
13975
13793
 
@@ -13984,12 +13802,6 @@ WaveformData.prototype = {
13984
13802
 
13985
13803
  /**
13986
13804
  * Return the unpacked values for a particular offset.
13987
- *
13988
- * @param {Integer} start
13989
- * @param {Integer} length
13990
- * @param {Integer} correction The step to skip for each iteration
13991
- * (as the response body is [min, max, min, max...])
13992
- * @return {Array.<Integer>}
13993
13805
  */
13994
13806
 
13995
13807
  _offsetValues: function getOffsetValues(start, length, correction) {
@@ -14008,14 +13820,6 @@ WaveformData.prototype = {
14008
13820
 
14009
13821
  /**
14010
13822
  * Returns the length of the waveform, in pixels.
14011
- *
14012
- * ```javascript
14013
- * var waveform = WaveformData.create({ ... });
14014
- * console.log(waveform.length); // -> 600
14015
- * ```
14016
- *
14017
- * @api
14018
- * @return {Integer} Length of the waveform, in pixels.
14019
13823
  */
14020
13824
 
14021
13825
  get length() {
@@ -14032,14 +13836,6 @@ WaveformData.prototype = {
14032
13836
 
14033
13837
  /**
14034
13838
  * Returns the (approximate) duration of the audio file, in seconds.
14035
- *
14036
- * ```javascript
14037
- * var waveform = WaveformData.create({ ... });
14038
- * console.log(waveform.duration); // -> 10.33333333333
14039
- * ```
14040
- *
14041
- * @api
14042
- * @return {number} Duration of the audio waveform, in seconds.
14043
13839
  */
14044
13840
 
14045
13841
  get duration() {
@@ -14047,16 +13843,7 @@ WaveformData.prototype = {
14047
13843
  },
14048
13844
 
14049
13845
  /**
14050
- * Return the number of pixels per second.
14051
- *
14052
- * ```javascript
14053
- * var waveform = WaveformData.create({ ... });
14054
- *
14055
- * console.log(waveform.pixels_per_second); // -> 93.75
14056
- * ```
14057
- *
14058
- * @api
14059
- * @return {number} Number of pixels per second.
13846
+ * Returns the number of pixels per second.
14060
13847
  */
14061
13848
 
14062
13849
  get pixels_per_second() {
@@ -14064,15 +13851,7 @@ WaveformData.prototype = {
14064
13851
  },
14065
13852
 
14066
13853
  /**
14067
- * Return the amount of time represented by a single pixel.
14068
- *
14069
- * ```javascript
14070
- * var waveform = WaveformData.create({ ... });
14071
- *
14072
- * console.log(waveform.seconds_per_pixel); // -> 0.010666666666666666
14073
- * ```
14074
- *
14075
- * @return {number} Amount of time (in seconds) contained in a pixel.
13854
+ * Returns the amount of time represented by a single pixel, in seconds.
14076
13855
  */
14077
13856
 
14078
13857
  get seconds_per_pixel() {
@@ -14081,14 +13860,6 @@ WaveformData.prototype = {
14081
13860
 
14082
13861
  /**
14083
13862
  * Returns the number of waveform channels.
14084
- *
14085
- * ```javascript
14086
- * var waveform = WaveformData.create({ ... });
14087
- * console.log(waveform.channels); // -> 1
14088
- * ```
14089
- *
14090
- * @api
14091
- * @return {number} Number of channels.
14092
13863
  */
14093
13864
 
14094
13865
  get channels() {
@@ -14097,16 +13868,6 @@ WaveformData.prototype = {
14097
13868
 
14098
13869
  /**
14099
13870
  * Returns a waveform channel.
14100
- *
14101
- * ```javascript
14102
- * var waveform = WaveformData.create({ ... });
14103
- * var channel = waveform.channel(0);
14104
- * console.log(channel.min_sample(0)); // -> 1
14105
- * ```
14106
- *
14107
- * @api
14108
- * @param {Number} Channel index.
14109
- * @return {WaveformDataChannel} Waveform channel.
14110
13871
  */
14111
13872
 
14112
13873
  channel: function(index) {
@@ -14119,9 +13880,7 @@ WaveformData.prototype = {
14119
13880
  },
14120
13881
 
14121
13882
  /**
14122
- * Returns the number of samples per second.
14123
- *
14124
- * @return {Integer} Number of samples per second.
13883
+ * Returns the number of audio samples per second.
14125
13884
  */
14126
13885
 
14127
13886
  get sample_rate() {
@@ -14129,9 +13888,7 @@ WaveformData.prototype = {
14129
13888
  },
14130
13889
 
14131
13890
  /**
14132
- * Returns the scale (number of samples per pixel).
14133
- *
14134
- * @return {Integer} Number of samples per pixel.
13891
+ * Returns the number of audio samples per pixel.
14135
13892
  */
14136
13893
 
14137
13894
  get scale() {
@@ -14139,10 +13896,7 @@ WaveformData.prototype = {
14139
13896
  },
14140
13897
 
14141
13898
  /**
14142
- * Returns the pixel location for a given time.
14143
- *
14144
- * @param {number} time
14145
- * @return {integer} Index location for a specific time.
13899
+ * Returns the waveform data index position for a given time.
14146
13900
  */
14147
13901
 
14148
13902
  at_time: function at_time(time) {
@@ -14150,14 +13904,36 @@ WaveformData.prototype = {
14150
13904
  },
14151
13905
 
14152
13906
  /**
14153
- * Returns the time in seconds for a given index
14154
- *
14155
- * @param {Integer} index
14156
- * @return {number}
13907
+ * Returns the time in seconds for a given index.
14157
13908
  */
14158
13909
 
14159
13910
  time: function time(index) {
14160
13911
  return index * this.scale / this.sample_rate;
13912
+ },
13913
+
13914
+ /**
13915
+ * Returns an object containing the waveform data.
13916
+ */
13917
+
13918
+ toJSON: function() {
13919
+ const waveform = {
13920
+ version: 2,
13921
+ channels: this.channels,
13922
+ sample_rate: this.sample_rate,
13923
+ samples_per_pixel: this.scale,
13924
+ bits: this.bits,
13925
+ length: this.length,
13926
+ data: []
13927
+ };
13928
+
13929
+ for (var i = 0; i < this.length; i++) {
13930
+ for (var channel = 0; channel < this.channels; channel++) {
13931
+ waveform.data.push(this.channel(channel).min_sample(i));
13932
+ waveform.data.push(this.channel(channel).max_sample(i));
13933
+ }
13934
+ }
13935
+
13936
+ return waveform;
14161
13937
  }
14162
13938
  };
14163
13939
 
@@ -14166,13 +13942,54 @@ module.exports = WaveformData;
14166
13942
  },{"./adapters/arraybuffer":77,"./adapters/object":78,"./channel":82}],84:[function(_dereq_,module,exports){
14167
13943
  "use strict";
14168
13944
 
13945
+ function MainThreadWorker(func) {
13946
+ this._listeners = {};
13947
+
13948
+ func.call(this);
13949
+ }
13950
+
13951
+ MainThreadWorker.prototype.addEventListener = function(event, listener) {
13952
+ if (!this._listeners[event]) {
13953
+ this._listeners[event] = [];
13954
+ }
13955
+
13956
+ this._listeners[event].push(listener);
13957
+ };
13958
+
13959
+ MainThreadWorker.prototype.removeEventListener = function(event, listener) {
13960
+ if (this._listeners[event]) {
13961
+ this._listeners[event] = this._listeners[event].filter(function(item) {
13962
+ return item !== listener;
13963
+ });
13964
+ }
13965
+ };
13966
+
13967
+ MainThreadWorker.prototype.postMessage = function(data) {
13968
+ var event = { data: data };
13969
+
13970
+ var listeners = this._listeners.message;
13971
+
13972
+ for (var i = 0; i < listeners.length; i++) {
13973
+ listeners[i].call(this, event);
13974
+ }
13975
+ };
13976
+
13977
+ MainThreadWorker.prototype.close = function() {
13978
+ this._listeners = {};
13979
+ };
13980
+
13981
+ module.exports = MainThreadWorker;
13982
+
13983
+ },{}],85:[function(_dereq_,module,exports){
13984
+ "use strict";
13985
+
14169
13986
  var WaveformData = _dereq_("./lib/core");
14170
13987
 
14171
13988
  WaveformData.createFromAudio = _dereq_("./lib/builders/webaudio");
14172
13989
 
14173
13990
  module.exports = WaveformData;
14174
13991
 
14175
- },{"./lib/builders/webaudio":81,"./lib/core":83}],85:[function(_dereq_,module,exports){
13992
+ },{"./lib/builders/webaudio":81,"./lib/core":83}],86:[function(_dereq_,module,exports){
14176
13993
  module.exports = function (Data) {
14177
13994
  'use strict';
14178
13995
  function DataRetriever(peaks) {
@@ -14222,7 +14039,7 @@ module.exports = function (Data) {
14222
14039
  };
14223
14040
  return DataRetriever;
14224
14041
  }(_dereq_('./data'));
14225
- },{"./data":86}],86:[function(_dereq_,module,exports){
14042
+ },{"./data":87}],87:[function(_dereq_,module,exports){
14226
14043
  module.exports = function () {
14227
14044
  'use strict';
14228
14045
  function Data(type, content) {
@@ -14254,7 +14071,7 @@ module.exports = function () {
14254
14071
  };
14255
14072
  return Data;
14256
14073
  }();
14257
- },{}],87:[function(_dereq_,module,exports){
14074
+ },{}],88:[function(_dereq_,module,exports){
14258
14075
  module.exports = function (Utils, Konva) {
14259
14076
  'use strict';
14260
14077
  function DefaultSegmentMarker(options) {
@@ -14338,7 +14155,7 @@ module.exports = function (Utils, Konva) {
14338
14155
  };
14339
14156
  return DefaultSegmentMarker;
14340
14157
  }(_dereq_('./utils'), _dereq_('konva'));
14341
- },{"./utils":110,"konva":43}],88:[function(_dereq_,module,exports){
14158
+ },{"./utils":111,"konva":43}],89:[function(_dereq_,module,exports){
14342
14159
  module.exports = function () {
14343
14160
  'use strict';
14344
14161
  function Invoker() {
@@ -14387,7 +14204,7 @@ module.exports = function () {
14387
14204
  };
14388
14205
  return Invoker;
14389
14206
  }();
14390
- },{}],89:[function(_dereq_,module,exports){
14207
+ },{}],90:[function(_dereq_,module,exports){
14391
14208
  module.exports = function () {
14392
14209
  'use strict';
14393
14210
  var nodes = [
@@ -14470,7 +14287,7 @@ module.exports = function () {
14470
14287
  };
14471
14288
  return KeyboardHandler;
14472
14289
  }();
14473
- },{}],90:[function(_dereq_,module,exports){
14290
+ },{}],91:[function(_dereq_,module,exports){
14474
14291
  module.exports = function (Konva, Utils) {
14475
14292
  'use strict';
14476
14293
  function LineIndicator(peaks, view, container) {
@@ -14691,7 +14508,7 @@ module.exports = function (Konva, Utils) {
14691
14508
  };
14692
14509
  return LineIndicator;
14693
14510
  }(_dereq_('konva'), _dereq_('./utils'));
14694
- },{"./utils":110,"konva":43}],91:[function(_dereq_,module,exports){
14511
+ },{"./utils":111,"konva":43}],92:[function(_dereq_,module,exports){
14695
14512
  module.exports = function (Konva, Utils) {
14696
14513
  'use strict';
14697
14514
  function Line(peaks, view, y, id, position) {
@@ -15154,7 +14971,7 @@ module.exports = function (Konva, Utils) {
15154
14971
  };
15155
14972
  return Line;
15156
14973
  }(_dereq_('konva'), _dereq_('./utils'));
15157
- },{"./utils":110,"konva":43}],92:[function(_dereq_,module,exports){
14974
+ },{"./utils":111,"konva":43}],93:[function(_dereq_,module,exports){
15158
14975
  module.exports = function (SegmentsGroup, Line, LineIndicator, Utils) {
15159
14976
  'use strict';
15160
14977
  function Lines(peaks, view, layer) {
@@ -15453,7 +15270,7 @@ module.exports = function (SegmentsGroup, Line, LineIndicator, Utils) {
15453
15270
  };
15454
15271
  return Lines;
15455
15272
  }(_dereq_('./segments-group'), _dereq_('./line'), _dereq_('./line-indicator'), _dereq_('./utils'));
15456
- },{"./line":91,"./line-indicator":90,"./segments-group":102,"./utils":110}],93:[function(_dereq_,module,exports){
15273
+ },{"./line":92,"./line-indicator":91,"./segments-group":103,"./utils":111}],94:[function(_dereq_,module,exports){
15457
15274
  module.exports = function (Colors, EventEmitter, TimelineSegments, TimelineSources, KeyboardHandler, Player, MarkerFactories, TimelineZoomView, Utils) {
15458
15275
  'use strict';
15459
15276
  function Peaks() {
@@ -15692,7 +15509,7 @@ module.exports = function (Colors, EventEmitter, TimelineSegments, TimelineSourc
15692
15509
  };
15693
15510
  return Peaks;
15694
15511
  }(_dereq_('colors.css'), _dereq_('eventemitter2'), _dereq_('./timeline-segments'), _dereq_('./timeline-sources'), _dereq_('./keyboard-handler'), _dereq_('./player'), _dereq_('./marker-factories'), _dereq_('./timeline-zoomview'), _dereq_('./utils'));
15695
- },{"./keyboard-handler":89,"./marker-factories":94,"./player":97,"./timeline-segments":107,"./timeline-sources":108,"./timeline-zoomview":109,"./utils":110,"colors.css":1,"eventemitter2":2}],94:[function(_dereq_,module,exports){
15512
+ },{"./keyboard-handler":90,"./marker-factories":95,"./player":98,"./timeline-segments":108,"./timeline-sources":109,"./timeline-zoomview":110,"./utils":111,"colors.css":1,"eventemitter2":2}],95:[function(_dereq_,module,exports){
15696
15513
  module.exports = function (DefaultSegmentMarker, Utils, Konva) {
15697
15514
  'use strict';
15698
15515
  function createSegmentMarker(options) {
@@ -15724,7 +15541,7 @@ module.exports = function (DefaultSegmentMarker, Utils, Konva) {
15724
15541
  createSegmentLabel: createSegmentLabel
15725
15542
  };
15726
15543
  }(_dereq_('./default-segment-marker'), _dereq_('./utils'), _dereq_('konva'));
15727
- },{"./default-segment-marker":87,"./utils":110,"konva":43}],95:[function(_dereq_,module,exports){
15544
+ },{"./default-segment-marker":88,"./utils":111,"konva":43}],96:[function(_dereq_,module,exports){
15728
15545
  module.exports = function (Utils, SourceGroup, Konva) {
15729
15546
  'use strict';
15730
15547
  var TIME_X_OFFSET = 20;
@@ -15996,7 +15813,7 @@ module.exports = function (Utils, SourceGroup, Konva) {
15996
15813
  };
15997
15814
  return ModeLayer;
15998
15815
  }(_dereq_('./utils'), _dereq_('./source-group'), _dereq_('konva'));
15999
- },{"./source-group":103,"./utils":110,"konva":43}],96:[function(_dereq_,module,exports){
15816
+ },{"./source-group":104,"./utils":111,"konva":43}],97:[function(_dereq_,module,exports){
16000
15817
  module.exports = function (Konva) {
16001
15818
  'use strict';
16002
15819
  function getMarkerObject(obj) {
@@ -16092,7 +15909,7 @@ module.exports = function (Konva) {
16092
15909
  };
16093
15910
  return MouseDragHandler;
16094
15911
  }(_dereq_('konva'));
16095
- },{"konva":43}],97:[function(_dereq_,module,exports){
15912
+ },{"konva":43}],98:[function(_dereq_,module,exports){
16096
15913
  module.exports = function (Utils) {
16097
15914
  'use strict';
16098
15915
  function Player(peaks) {
@@ -16176,7 +15993,7 @@ module.exports = function (Utils) {
16176
15993
  };
16177
15994
  return Player;
16178
15995
  }(_dereq_('./utils'));
16179
- },{"./utils":110}],98:[function(_dereq_,module,exports){
15996
+ },{"./utils":111}],99:[function(_dereq_,module,exports){
16180
15997
  module.exports = function (Utils, Konva) {
16181
15998
  'use strict';
16182
15999
  var HANDLE_RADIUS = 10;
@@ -16421,7 +16238,7 @@ module.exports = function (Utils, Konva) {
16421
16238
  };
16422
16239
  return PlayheadLayer;
16423
16240
  }(_dereq_('./utils'), _dereq_('konva'));
16424
- },{"./utils":110,"konva":43}],99:[function(_dereq_,module,exports){
16241
+ },{"./utils":111,"konva":43}],100:[function(_dereq_,module,exports){
16425
16242
  module.exports = function (Konva) {
16426
16243
  'use strict';
16427
16244
  function SegmentMarker(options) {
@@ -16507,7 +16324,7 @@ module.exports = function (Konva) {
16507
16324
  };
16508
16325
  return SegmentMarker;
16509
16326
  }(_dereq_('konva'));
16510
- },{"konva":43}],100:[function(_dereq_,module,exports){
16327
+ },{"konva":43}],101:[function(_dereq_,module,exports){
16511
16328
  module.exports = function (Konva, SegmentMarker) {
16512
16329
  'use strict';
16513
16330
  var SEGMENT_WIDTH = 10;
@@ -16681,7 +16498,7 @@ module.exports = function (Konva, SegmentMarker) {
16681
16498
  SegmentShape.prototype._onMouseEnter = function () {
16682
16499
  this._view.setCursor('pointer');
16683
16500
  this._view.setHoveredElement(this);
16684
- this._rectangle.fill(this._segment.activeColor + Math.round(this._segment.opacity * 255).toString(16));
16501
+ this._rectangle.fill(this._segment.hoverColor + Math.round(this._segment.opacity * 255).toString(16));
16685
16502
  this._view.drawSourcesLayer();
16686
16503
  this._peaks.emit('segments.mouseenter', this._segment);
16687
16504
  };
@@ -16744,7 +16561,7 @@ module.exports = function (Konva, SegmentMarker) {
16744
16561
  };
16745
16562
  return SegmentShape;
16746
16563
  }(_dereq_('konva'), _dereq_('./segment-marker'));
16747
- },{"./segment-marker":99,"konva":43}],101:[function(_dereq_,module,exports){
16564
+ },{"./segment-marker":100,"konva":43}],102:[function(_dereq_,module,exports){
16748
16565
  module.exports = function (Utils) {
16749
16566
  'use strict';
16750
16567
  function validateSegment(peaks, options, context) {
@@ -16782,8 +16599,13 @@ module.exports = function (Utils) {
16782
16599
  } else if (!Utils.isBoolean(options.editable)) {
16783
16600
  throw new TypeError('peaks.segments.' + context + ': editable must be a boolean');
16784
16601
  }
16602
+ if (Utils.isNullOrUndefined(options.hoverColor)) {
16603
+ options.hoverColor = Utils.shadeColor(options.color, 20);
16604
+ } else if (!Utils.isValidColor(options.hoverColor)) {
16605
+ throw new TypeError('peaks.segments.' + context + ': hoverColor must be a boolean');
16606
+ }
16785
16607
  }
16786
- function Segment(peaks, id, startTime, endTime, labelText, color, textColor, handleTextColor, opacity, editable, allowDeletion, line) {
16608
+ function Segment(peaks, id, startTime, endTime, labelText, color, textColor, handleTextColor, hoverColor, opacity, editable, allowDeletion, line) {
16787
16609
  var opts = {
16788
16610
  startTime: startTime,
16789
16611
  endTime: endTime,
@@ -16791,6 +16613,7 @@ module.exports = function (Utils) {
16791
16613
  color: color,
16792
16614
  textColor: textColor,
16793
16615
  handleTextColor: handleTextColor,
16616
+ hoverColor: hoverColor,
16794
16617
  opacity: opacity,
16795
16618
  editable: editable,
16796
16619
  allowDeletion: allowDeletion,
@@ -16803,7 +16626,7 @@ module.exports = function (Utils) {
16803
16626
  this._endTime = opts.endTime;
16804
16627
  this._labelText = opts.labelText;
16805
16628
  this._color = opts.color;
16806
- this._activeColor = Utils.shadeColor(color, 20);
16629
+ this._hoverColor = opts.hoverColor;
16807
16630
  this._textColor = opts.textColor;
16808
16631
  this._handleTextColor = opts.handleTextColor;
16809
16632
  this._opacity = opts.opacity;
@@ -16849,10 +16672,10 @@ module.exports = function (Utils) {
16849
16672
  return this._color;
16850
16673
  }
16851
16674
  },
16852
- activeColor: {
16675
+ hoverColor: {
16853
16676
  enumerable: true,
16854
16677
  get: function () {
16855
- return this._activeColor;
16678
+ return this._hoverColor;
16856
16679
  }
16857
16680
  },
16858
16681
  textColor: {
@@ -16906,6 +16729,7 @@ module.exports = function (Utils) {
16906
16729
  color: this.color,
16907
16730
  textColor: this.textColor,
16908
16731
  handleTextColor: this.handleTextColor,
16732
+ hoverColor: this.hoverColor,
16909
16733
  opacity: this.opacity,
16910
16734
  editable: this.editable,
16911
16735
  allowDeletion: this.allowDeletion,
@@ -16919,6 +16743,7 @@ module.exports = function (Utils) {
16919
16743
  this._color = opts.color;
16920
16744
  this._textColor = opts.textColor;
16921
16745
  this._handleTextColor = opts.handleTextColor;
16746
+ this._hoverColor = opts.hoverColor;
16922
16747
  this._opacity = opts.opacity;
16923
16748
  this._editable = opts.editable;
16924
16749
  this._allowDeletion = opts.allowDeletion;
@@ -16930,7 +16755,7 @@ module.exports = function (Utils) {
16930
16755
  };
16931
16756
  return Segment;
16932
16757
  }(_dereq_('./utils'));
16933
- },{"./utils":110}],102:[function(_dereq_,module,exports){
16758
+ },{"./utils":111}],103:[function(_dereq_,module,exports){
16934
16759
  module.exports = function (SegmentShape, Utils, Konva) {
16935
16760
  'use strict';
16936
16761
  function SegmentsGroup(peaks, view, allowEditing) {
@@ -17427,7 +17252,7 @@ module.exports = function (SegmentShape, Utils, Konva) {
17427
17252
  };
17428
17253
  return SegmentsGroup;
17429
17254
  }(_dereq_('./segment-shape'), _dereq_('./utils'), _dereq_('konva'));
17430
- },{"./segment-shape":100,"./utils":110,"konva":43}],103:[function(_dereq_,module,exports){
17255
+ },{"./segment-shape":101,"./utils":111,"konva":43}],104:[function(_dereq_,module,exports){
17431
17256
  module.exports = function (WaveformBuilder, WaveformShape, Utils, Konva) {
17432
17257
  'use strict';
17433
17258
  var SPACING_BETWEEN_PREVIEW_AND_BORDER_RATIO = 0.15;
@@ -18132,7 +17957,7 @@ module.exports = function (WaveformBuilder, WaveformShape, Utils, Konva) {
18132
17957
  };
18133
17958
  return SourceGroup;
18134
17959
  }(_dereq_('./waveform-builder'), _dereq_('./waveform-shape'), _dereq_('./utils'), _dereq_('konva'));
18135
- },{"./utils":110,"./waveform-builder":111,"./waveform-shape":112,"konva":43}],104:[function(_dereq_,module,exports){
17960
+ },{"./utils":111,"./waveform-builder":112,"./waveform-shape":113,"konva":43}],105:[function(_dereq_,module,exports){
18136
17961
  module.exports = function (Utils) {
18137
17962
  'use strict';
18138
17963
  function validateSource(peaks, options, context) {
@@ -18669,7 +18494,7 @@ module.exports = function (Utils) {
18669
18494
  };
18670
18495
  return Source;
18671
18496
  }(_dereq_('./utils'));
18672
- },{"./utils":110}],105:[function(_dereq_,module,exports){
18497
+ },{"./utils":111}],106:[function(_dereq_,module,exports){
18673
18498
  module.exports = function (SourceGroup, Lines, DataRetriever, Utils, Invoker, Konva) {
18674
18499
  'use strict';
18675
18500
  function SourcesLayer(peaks, view, allowEditing) {
@@ -19016,7 +18841,7 @@ module.exports = function (SourceGroup, Lines, DataRetriever, Utils, Invoker, Ko
19016
18841
  };
19017
18842
  return SourcesLayer;
19018
18843
  }(_dereq_('./source-group'), _dereq_('./lines'), _dereq_('./data-retriever'), _dereq_('./utils'), _dereq_('./invoker'), _dereq_('konva'));
19019
- },{"./data-retriever":85,"./invoker":88,"./lines":92,"./source-group":103,"./utils":110,"konva":43}],106:[function(_dereq_,module,exports){
18844
+ },{"./data-retriever":86,"./invoker":89,"./lines":93,"./source-group":104,"./utils":111,"konva":43}],107:[function(_dereq_,module,exports){
19020
18845
  module.exports = function (Utils, Konva) {
19021
18846
  'use strict';
19022
18847
  var LEFT_PADDING = 4;
@@ -19157,7 +18982,7 @@ module.exports = function (Utils, Konva) {
19157
18982
  };
19158
18983
  return TimelineAxis;
19159
18984
  }(_dereq_('./utils'), _dereq_('konva'));
19160
- },{"./utils":110,"konva":43}],107:[function(_dereq_,module,exports){
18985
+ },{"./utils":111,"konva":43}],108:[function(_dereq_,module,exports){
19161
18986
  module.exports = function (Colors, Segment, Utils) {
19162
18987
  'use strict';
19163
18988
  function TimelineSegments(peaks) {
@@ -19200,7 +19025,7 @@ module.exports = function (Colors, Segment, Utils) {
19200
19025
  if (!Utils.isObject(options)) {
19201
19026
  throw new TypeError('peaks.segments.add(): expected a Segment object parameter');
19202
19027
  }
19203
- var segment = new Segment(this._peaks, Utils.isNullOrUndefined(options.id) ? this._getNextSegmentId() : options.id, options.startTime, options.endTime, options.labelText, options.color || this._getSegmentColor(), options.textColor || '#000000', options.handleTextColor || '#000000', options.opacity || 1, options.editable, options.allowDeletion || false, options.line);
19028
+ var segment = new Segment(this._peaks, Utils.isNullOrUndefined(options.id) ? this._getNextSegmentId() : options.id, options.startTime, options.endTime, options.labelText, options.color || this._getSegmentColor(), options.textColor || '#000000', options.handleTextColor || '#000000', options.hoverColor, options.opacity || 1, options.editable, options.allowDeletion || false, options.line);
19204
19029
  return segment;
19205
19030
  };
19206
19031
  TimelineSegments.prototype.getSegments = function () {
@@ -19307,7 +19132,7 @@ module.exports = function (Colors, Segment, Utils) {
19307
19132
  };
19308
19133
  return TimelineSegments;
19309
19134
  }(_dereq_('colors.css'), _dereq_('./segment'), _dereq_('./utils'));
19310
- },{"./segment":101,"./utils":110,"colors.css":1}],108:[function(_dereq_,module,exports){
19135
+ },{"./segment":102,"./utils":111,"colors.css":1}],109:[function(_dereq_,module,exports){
19311
19136
  module.exports = function (Source, Utils) {
19312
19137
  'use strict';
19313
19138
  function TimelineSources(peaks) {
@@ -19474,7 +19299,7 @@ module.exports = function (Source, Utils) {
19474
19299
  };
19475
19300
  return TimelineSources;
19476
19301
  }(_dereq_('./source'), _dereq_('./utils'));
19477
- },{"./source":104,"./utils":110}],109:[function(_dereq_,module,exports){
19302
+ },{"./source":105,"./utils":111}],110:[function(_dereq_,module,exports){
19478
19303
  module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLayer, TimelineAxis, Utils, Konva) {
19479
19304
  'use strict';
19480
19305
  function TimelineZoomView(container, peaks) {
@@ -19940,9 +19765,6 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
19940
19765
  var frameStartTime = null;
19941
19766
  var frameEndTime = null;
19942
19767
  if (frameOffset !== undefined && frameOffset !== null) {
19943
- if (this._timelineLength < this._width) {
19944
- frameOffset = 0;
19945
- }
19946
19768
  this.setFrameOffset(frameOffset);
19947
19769
  frameStartTime = this.pixelsToTime(this._frameOffset);
19948
19770
  frameEndTime = this.pixelsToTime(this._frameOffset + this._width);
@@ -20026,7 +19848,7 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
20026
19848
  };
20027
19849
  return TimelineZoomView;
20028
19850
  }(_dereq_('./mouse-drag-handler'), _dereq_('./playhead-layer'), _dereq_('./sources-layer'), _dereq_('./mode-layer'), _dereq_('./timeline-axis'), _dereq_('./utils'), _dereq_('konva'));
20029
- },{"./mode-layer":95,"./mouse-drag-handler":96,"./playhead-layer":98,"./sources-layer":105,"./timeline-axis":106,"./utils":110,"konva":43}],110:[function(_dereq_,module,exports){
19851
+ },{"./mode-layer":96,"./mouse-drag-handler":97,"./playhead-layer":99,"./sources-layer":106,"./timeline-axis":107,"./utils":111,"konva":43}],111:[function(_dereq_,module,exports){
20030
19852
  module.exports = function (UUID) {
20031
19853
  'use strict';
20032
19854
  if (typeof Number.isFinite !== 'function') {
@@ -20190,7 +20012,7 @@ module.exports = function (UUID) {
20190
20012
  }
20191
20013
  };
20192
20014
  }(_dereq_('uuid'));
20193
- },{"uuid":62}],111:[function(_dereq_,module,exports){
20015
+ },{"uuid":62}],112:[function(_dereq_,module,exports){
20194
20016
  module.exports = function (WaveformData, Utils) {
20195
20017
  'use strict';
20196
20018
  var isXhr2 = 'withCredentials' in new XMLHttpRequest();
@@ -20382,7 +20204,7 @@ module.exports = function (WaveformData, Utils) {
20382
20204
  };
20383
20205
  return WaveformBuilder;
20384
20206
  }(_dereq_('waveform-data'), _dereq_('./utils'));
20385
- },{"./utils":110,"waveform-data":84}],112:[function(_dereq_,module,exports){
20207
+ },{"./utils":111,"waveform-data":85}],113:[function(_dereq_,module,exports){
20386
20208
  module.exports = function (Utils, Konva) {
20387
20209
  'use strict';
20388
20210
  function scaleY(amplitude, height, scale) {
@@ -20475,6 +20297,6 @@ module.exports = function (Utils, Konva) {
20475
20297
  };
20476
20298
  return WaveformShape;
20477
20299
  }(_dereq_('./utils'), _dereq_('konva'));
20478
- },{"./utils":110,"konva":43}]},{},[93])(93)
20300
+ },{"./utils":111,"konva":43}]},{},[94])(94)
20479
20301
  });
20480
20302
  //# sourceMappingURL=peaks.js.map