2846 lines
75 KiB
JavaScript
Executable File
2846 lines
75 KiB
JavaScript
Executable File
(function (w, d, PKAE) {
|
|
'use strict';
|
|
|
|
function PKEng(app) {
|
|
var q = this;
|
|
|
|
var wavesurfer = WaveSurfer.create({
|
|
container: '#' + 'pk_av_' + app.id,
|
|
scrollParent: false,
|
|
hideScrollbar: true,
|
|
partialRender: false,
|
|
fillParent: false,
|
|
pixelRatio: 1,
|
|
progressColor: 'rgba(79, 70, 229, 0.4)',
|
|
splitChannels: true,
|
|
autoCenter: true,
|
|
height: w.innerHeight - 168,
|
|
plugins: [
|
|
WaveSurfer.regions.create({
|
|
dragSelection: {
|
|
slop: 5
|
|
}
|
|
})
|
|
]
|
|
});
|
|
this.wavesurfer = wavesurfer;
|
|
|
|
var AudioUtils = new app._deps.audioutils(app, wavesurfer);
|
|
q.is_ready = false;
|
|
|
|
this.TrimTo = function (val, num) {
|
|
var nums = { '0': 1, '1': 10, '2': 100, '3': 1000, '4': 10000, '5': 100000 };
|
|
var dec = nums[num];
|
|
return ((val * dec) >> 0) / dec;
|
|
}
|
|
|
|
this.LoadArrayBuffer = function (e) {
|
|
var func = function () {
|
|
app.listenFor('RequestCancelModal', function () {
|
|
wavesurfer.cancelBufferLoad();
|
|
if (wavesurfer.arraybuffer) q.is_ready = true;
|
|
|
|
app.fireEvent('RequestResize');
|
|
setTimeout(function () { app.fireEvent('DidDownloadFile'); }, 12);
|
|
app.stopListeningForName('RequestCancelModal');
|
|
|
|
OneUp('Canceled Loading', 1350);
|
|
});
|
|
|
|
app.fireEvent('RequestZoomUI', 0);
|
|
|
|
app.fireEvent('WillDownloadFile');
|
|
q.is_ready = false;
|
|
wavesurfer.loadBlob(e);
|
|
app.fireEvent('DidUnloadFile');
|
|
|
|
wavesurfer.regions && wavesurfer.regions.clear();
|
|
};
|
|
|
|
if (q.is_ready) {
|
|
// ----------------
|
|
new PKSimpleModal({
|
|
title: 'Open or append',
|
|
clss: 'pk_modal_anim pk_fnt10',
|
|
ondestroy: function (q) {
|
|
app.ui.InteractionHandler.on = false;
|
|
app.ui.KeyHandler.removeCallback('modalTempErr');
|
|
},
|
|
buttons: [
|
|
{
|
|
title: 'OPEN NEW',
|
|
callback: function (q) {
|
|
wavesurfer.backend._add = 0;
|
|
func();
|
|
q.Destroy();
|
|
}
|
|
},
|
|
{
|
|
title: 'ADD IN EXISTING',
|
|
callback: function (q) {
|
|
wavesurfer.backend._add = 1;
|
|
func();
|
|
q.Destroy();
|
|
}
|
|
}
|
|
],
|
|
body: '<p>Append file to existing track?</p>',
|
|
setup: function (q) {
|
|
app.ui.InteractionHandler.checkAndSet('modal');
|
|
app.ui.KeyHandler.addCallback('modalTempErr', function (e) {
|
|
q.Destroy();
|
|
}, [27]);
|
|
}
|
|
}).Show();
|
|
|
|
return;
|
|
}
|
|
|
|
wavesurfer.backend._add = 0;
|
|
func();
|
|
// ---
|
|
};
|
|
|
|
this.LoadDB = function (e) {
|
|
var new_buffer = wavesurfer.backend.ac.createBuffer(
|
|
e.data.length,
|
|
e.data[0].byteLength / 4,
|
|
e.samplerate
|
|
);
|
|
|
|
for (var i = 0; i < e.data.length; ++i) {
|
|
|
|
var arr = new Float32Array(e.data[i]);
|
|
|
|
if (new_buffer.copyToChannel) {
|
|
new_buffer.copyToChannel(arr, i, 0);
|
|
}
|
|
else {
|
|
var chan = new_buffer.getChannelData(i);
|
|
chan.set(arr);
|
|
}
|
|
}
|
|
|
|
var append = wavesurfer.backend._add;
|
|
var old_durr = wavesurfer.getDuration();
|
|
|
|
PKAudioEditor.engine.wavesurfer.loadDecodedBuffer(new_buffer);
|
|
_compute_channels();
|
|
var new_durr = wavesurfer.getDuration();
|
|
app.fireEvent('DidUpdateLen', new_durr);
|
|
|
|
if (!append) app.fireEvent('RequestSeekTo', 0);
|
|
else {
|
|
wavesurfer.regions.clear();
|
|
wavesurfer.regions.add({
|
|
start: old_durr,
|
|
end: new_durr,
|
|
id: 't'
|
|
});
|
|
}
|
|
// --------
|
|
};
|
|
|
|
this.LoadFile = function (e) {
|
|
if (e.files.length > 0) {
|
|
if (e.files[0].type == "audio/mp3"
|
|
|| e.files[0].type == "audio/wave"
|
|
|| e.files[0].type == "audio/mpeg"
|
|
|| e.files[0].type == "audio/aiff"
|
|
|| e.files[0].type == "audio/flac"
|
|
|| e.files[0].type == "audio/ogg") {
|
|
|
|
var func = function () {
|
|
app.listenFor('RequestCancelModal', function () {
|
|
wavesurfer.cancelBufferLoad();
|
|
AudioUtils.DownloadFileCancel();
|
|
if (wavesurfer.arraybuffer) q.is_ready = true;
|
|
|
|
app.fireEvent('RequestResize');
|
|
setTimeout(function () {
|
|
app.fireEvent('DidDownloadFile');
|
|
}, 12);
|
|
app.stopListeningForName('RequestCancelModal');
|
|
|
|
OneUp('Canceled Loading', 1350);
|
|
});
|
|
|
|
app.fireEvent('WillDownloadFile');
|
|
q.is_ready = false;
|
|
wavesurfer.loadBlob(e.files[0]);
|
|
app.fireEvent('DidUnloadFile');
|
|
wavesurfer.regions && wavesurfer.regions.clear();
|
|
};
|
|
|
|
if (q.is_ready) {
|
|
// ----------------
|
|
new PKSimpleModal({
|
|
title: 'Open or append',
|
|
clss: 'pk_modal_anim pk_fnt10',
|
|
ondestroy: function (q) {
|
|
app.ui.InteractionHandler.on = false;
|
|
app.ui.KeyHandler.removeCallback('modalTempErr');
|
|
},
|
|
buttons: [
|
|
{
|
|
title: 'OPEN NEW',
|
|
callback: function (q) {
|
|
wavesurfer.backend._add = 0;
|
|
func();
|
|
q.Destroy();
|
|
}
|
|
},
|
|
{
|
|
title: 'ADD IN EXISTING',
|
|
callback: function (q) {
|
|
wavesurfer.backend._add = 1;
|
|
func();
|
|
q.Destroy();
|
|
}
|
|
}
|
|
],
|
|
body: '<p>Append file to existing track?</p>',
|
|
setup: function (q) {
|
|
app.ui.InteractionHandler.checkAndSet('modal');
|
|
app.ui.KeyHandler.addCallback('modalTempErr', function (e) {
|
|
q.Destroy();
|
|
}, [27]);
|
|
}
|
|
}).Show();
|
|
|
|
return;
|
|
}
|
|
|
|
wavesurfer.backend._add = 0;
|
|
func();
|
|
|
|
// ----
|
|
}
|
|
}
|
|
};
|
|
|
|
this.DownloadFile = function (name, format, kbps, selection, stereo) {
|
|
if (!q.is_ready) return;
|
|
|
|
app.fireEvent('WillDownloadFile');
|
|
|
|
app.listenFor('RequestCancelModal', function () {
|
|
AudioUtils.DownloadFileCancel();
|
|
if (wavesurfer.arraybuffer) q.is_ready = true;
|
|
|
|
app.fireEvent('RequestResize');
|
|
setTimeout(function () { app.fireEvent('DidDownloadFile'); }, 12);
|
|
app.stopListeningForName('RequestCancelModal');
|
|
});
|
|
|
|
setTimeout(function () {
|
|
AudioUtils.DownloadFile(name, format, kbps, selection, stereo, function (val) {
|
|
if (val === 'done') {
|
|
setTimeout(function () { app.fireEvent('DidDownloadFile'); }, 12);
|
|
app.stopListeningForName('RequestCancelModal');
|
|
}
|
|
else
|
|
app.fireEvent('DidProgressModal', val);
|
|
});
|
|
}, 220);
|
|
}
|
|
this.LoadSample = function () {
|
|
|
|
app.fireEvent('WillDownloadFile');
|
|
|
|
setTimeout(function () {
|
|
|
|
app.listenFor('RequestCancelModal', function () {
|
|
if (wavesurfer.cancelAjax()) {
|
|
if (wavesurfer.arraybuffer) q.is_ready = true;
|
|
|
|
app.fireEvent('RequestResize');
|
|
setTimeout(function () { app.fireEvent('DidDownloadFile'); }, 12);
|
|
app.stopListeningForName('RequestCancelModal');
|
|
|
|
OneUp('Canceled Loading', 1380);
|
|
}
|
|
});
|
|
|
|
app.fireEvent('RequestZoomUI', 0);
|
|
q.is_ready = false;
|
|
wavesurfer.load('test.mp3');
|
|
}, 180);
|
|
}
|
|
this.LoadURL = function (url) {
|
|
app.fireEvent('WillDownloadFile');
|
|
|
|
/*
|
|
var context = new AudioContext (); // wavesurfer.backend.ac;
|
|
var audio_el = d.createElement ('audio');
|
|
audio_el.autoplay = true;
|
|
audio_el.controls = true;
|
|
audio_el.preload = true;
|
|
// audio_el.playbackRate = 0.5;
|
|
d.body.appendChild( audio_el );
|
|
audio_el.src = url;
|
|
|
|
setTimeout(function() {
|
|
var source = context.createMediaElementSource (audio_el);
|
|
// source.connect(context.destination);
|
|
|
|
var time_duration = audio_el.duration / 1;
|
|
var first = true;
|
|
var audio_buffer = null;
|
|
var sample_rate = 0;
|
|
var chans = 0;
|
|
|
|
var scriptNode = context.createScriptProcessor (4096, 1, 1);
|
|
window.sss = scriptNode;
|
|
window.eee = source;
|
|
window.ccc = context;
|
|
|
|
var prev_time = 0;
|
|
|
|
scriptNode.onaudioprocess = function( ev ) {
|
|
if (audio_el.paused) return ;
|
|
|
|
var ctime = audio_el.currentTime / 1;
|
|
|
|
if ((ctime + 0.0001) >= time_duration)
|
|
{
|
|
//if (!first) {
|
|
// console.log ("done");
|
|
// first = 100;
|
|
//}
|
|
return ;
|
|
}
|
|
|
|
var inputBuffer = ev.inputBuffer;
|
|
// var outputBuffer = ev.outputBuffer;
|
|
|
|
if (first) {
|
|
first = false;
|
|
|
|
sample_rate = inputBuffer.sampleRate;
|
|
chans = inputBuffer.numberOfChannels;
|
|
audio_buffer = context.createBuffer (
|
|
inputBuffer.numberOfChannels,
|
|
time_duration * inputBuffer.sampleRate,
|
|
inputBuffer.sampleRate
|
|
);
|
|
|
|
window.audio_buffer = audio_buffer;
|
|
}
|
|
|
|
var curr_time = (ctime * sample_rate) >> 0;
|
|
|
|
// console.log( curr_time, " ", (curr_time - prev_time), " ", ((curr_time - prev_time) > (4096*2))?true:false );
|
|
// prev_time = curr_time;
|
|
|
|
for (var channel = 0; channel < inputBuffer.numberOfChannels; ++channel) {
|
|
var inputData = inputBuffer.getChannelData(channel);
|
|
// var outputData = outputBuffer.getChannelData(channel);
|
|
var final_data = audio_buffer.getChannelData(channel);
|
|
|
|
// console.log( inputData );
|
|
|
|
// Loop through the 4096 samples
|
|
for (var sample = 0; sample < inputBuffer.length; ++sample) {
|
|
// make output equal to the same as the input
|
|
// outputData[sample] = inputData[sample];
|
|
|
|
final_data[curr_time + sample] = inputData[sample];
|
|
|
|
// add noise to each output sample
|
|
// outputData[sample] += ((Math.random() * 2) - 1) * 0.2;
|
|
}
|
|
}
|
|
};
|
|
|
|
source.connect(scriptNode);
|
|
scriptNode.connect(context.destination);
|
|
},2000);
|
|
*/
|
|
|
|
setTimeout(function () {
|
|
app.listenFor('RequestCancelModal', function () {
|
|
if (wavesurfer.cancelAjax()) {
|
|
if (wavesurfer.arraybuffer) q.is_ready = true;
|
|
|
|
app.fireEvent('RequestResize');
|
|
setTimeout(function () { app.fireEvent('DidDownloadFile'); }, 12);
|
|
app.stopListeningForName('RequestCancelModal');
|
|
|
|
OneUp('Canceled Loading', 1350);
|
|
}
|
|
});
|
|
|
|
wavesurfer.load(url);
|
|
q.is_ready = false;
|
|
}, 180);
|
|
}
|
|
|
|
app.listenFor('RequestResize', function () {
|
|
wavesurfer.fireEvent('resize');
|
|
|
|
var h = window.innerHeight;
|
|
var bottom = 0;
|
|
|
|
if (app.ui && app.ui.BarBtm) {
|
|
bottom = (app.ui.BarBtm.on ? app.ui.BarBtm.height : 0);
|
|
}
|
|
|
|
wavesurfer.setHeight((h < 280 ? 280 : h) - 168 - bottom);
|
|
// app.fireEvent ('DidResize');
|
|
});
|
|
|
|
wavesurfer.on('ready', function () {
|
|
app.fireEvent('DidReadyFire');
|
|
|
|
if (wavesurfer.backend._add) {
|
|
wavesurfer.backend._add = 0;
|
|
}
|
|
|
|
if (q.is_ready) return;
|
|
q.is_ready = true;
|
|
|
|
// dirty hack for default message
|
|
var dirtymsg = document.getElementsByClassName('pk_tmpMsg');
|
|
if (dirtymsg.length > 0) {
|
|
dirtymsg = dirtymsg[0];
|
|
dirtymsg.parentNode.removeChild(dirtymsg);
|
|
}
|
|
|
|
copy_buffer = null;
|
|
app.fireEvent('DidDownloadFile');
|
|
|
|
app.fireEvent('StateRequestClearAll');
|
|
app.fireEvent('DidLoadFile');
|
|
app.fireEvent('DidUpdateLen', wavesurfer.getDuration());
|
|
app.fireEvent('DidSetClipboard', 0);
|
|
app.fireEvent('RequestSeekTo', 0);
|
|
|
|
app.fireEvent('RequestResize');
|
|
wavesurfer.getWaveEl().style.opacity = '1';
|
|
|
|
// loaded successfully
|
|
app.stopListeningForName('RequestCancelModal');
|
|
|
|
setTimeout(function () { OneUp('Loaded Successfully') }, 180);
|
|
|
|
// check if the audio file is mono or stereo and rebuild both UI and audio engine accordingly...
|
|
if (wavesurfer.backend.buffer.numberOfChannels === 1) {
|
|
wavesurfer.backend.SetNumberOfChannels(1);
|
|
wavesurfer.ActiveChannels = [1];
|
|
wavesurfer.drawer.params.ActiveChannels = wavesurfer.ActiveChannels;
|
|
wavesurfer.SelectedChannelsLen = 1;
|
|
|
|
app.el.classList.add('pk_mono');
|
|
} else if (wavesurfer.backend.buffer.numberOfChannels === 2) {
|
|
wavesurfer.backend.SetNumberOfChannels(2);
|
|
wavesurfer.ActiveChannels = [1, 1];
|
|
wavesurfer.drawer.params.ActiveChannels = wavesurfer.ActiveChannels;
|
|
wavesurfer.SelectedChannelsLen = 2;
|
|
|
|
app.el.classList.remove('pk_mono');
|
|
}
|
|
// ---
|
|
});
|
|
|
|
wavesurfer.on('pause', function () {
|
|
app.fireEvent('DidStopPlay');
|
|
});
|
|
wavesurfer.on('play', function () {
|
|
app.fireEvent('DidPlay');
|
|
});
|
|
wavesurfer.on('seek', function (where, stamp) {
|
|
var time = wavesurfer.getCurrentTime();
|
|
var loudness = wavesurfer.getLoudness();
|
|
|
|
app.fireEvent('DidAudioProcess', [time, loudness, stamp]);
|
|
});
|
|
|
|
app.listenFor('RequestStop', function (val) {
|
|
if (app.rec.isActive()) {
|
|
app.fireEvent('RequestActionRecordStop');
|
|
return (false);
|
|
}
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
if (region) wavesurfer.ActiveMarker = region.start / wavesurfer.getDuration();
|
|
|
|
wavesurfer.stop(val);
|
|
});
|
|
app.listenFor('RequestPlay', function (x) { // unique listener
|
|
if (q.in_fx) return;
|
|
|
|
app.fireEvent('RequestActionRecordStop');
|
|
|
|
if (!x && wavesurfer.isPlaying()) {
|
|
wavesurfer.stop();
|
|
wavesurfer.play();
|
|
}
|
|
else {
|
|
if (!app.rec.isActive()) {
|
|
wavesurfer.play();
|
|
} else {
|
|
setTimeout(function () {
|
|
if (!app.rec.isActive() && !x && !wavesurfer.isPlaying()) {
|
|
wavesurfer.play();
|
|
}
|
|
}, 220);
|
|
}
|
|
}
|
|
});
|
|
app.listenFor('RequestPause', function () {
|
|
app.fireEvent('RequestActionRecordStop');
|
|
wavesurfer.pause();
|
|
});
|
|
|
|
app.listenFor('RequestSetLoop', function () {
|
|
if (!q.is_ready) return;
|
|
|
|
var skip_seek = false;
|
|
|
|
if (wavesurfer.regions.list[0]) {
|
|
if (wavesurfer.regions.list[0].loop)
|
|
wavesurfer.regions.list[0].loop = false;
|
|
else
|
|
wavesurfer.regions.list[0].loop = true;
|
|
}
|
|
else {
|
|
skip_seek = true;
|
|
wavesurfer.regions.add({
|
|
start: 0.01,
|
|
end: wavesurfer.getDuration() - 0.01,
|
|
id: 't'
|
|
});
|
|
wavesurfer.regions.list[0].loop = true;
|
|
}
|
|
|
|
var will_loop = wavesurfer.regions.list[0].loop;
|
|
app.fireEvent('DidSetLoop', will_loop);
|
|
if (will_loop && !skip_seek /*&& wavesurfer.isPlaying ()*/) {
|
|
app.fireEvent('RequestSeekTo', wavesurfer.regions.list[0].start / wavesurfer.getDuration());
|
|
}
|
|
});
|
|
app.listenFor('RequestSkipBack', function (val) {
|
|
wavesurfer.skipBackward(val)
|
|
});
|
|
app.listenFor('RequestSkipFront', function (val) {
|
|
wavesurfer.skipForward(val);
|
|
});
|
|
app.listenFor('RequestSeekTo', function (val) {
|
|
if (val > 1.0) return;
|
|
wavesurfer.seekTo(val);
|
|
});
|
|
app.ui.KeyHandler.addCallback('zkA', function (key, m, e) {
|
|
e.preventDefault();
|
|
}, [38]);
|
|
app.ui.KeyHandler.addCallback('zkD', function (key, m, e) {
|
|
e.preventDefault();
|
|
}, [40]);
|
|
app.ui.KeyHandler.addSingleCallback('KeyPlayPause', function (e) {
|
|
if (app.ui.InteractionHandler.on) return;
|
|
e.preventDefault();
|
|
//e.stopPropagation();
|
|
}, 32);
|
|
|
|
app.ui.KeyHandler.addSingleCallback('KeyTilda', function (e) {
|
|
var open_el = app.ui.TopHeader.getOpenElement();
|
|
|
|
if (open_el) {
|
|
app.ui.TopHeader.closeMenu();
|
|
e.preventDefault();
|
|
return;
|
|
}
|
|
|
|
if (app.ui.InteractionHandler.on) return;
|
|
e.preventDefault();
|
|
|
|
app.ui.TopHeader.openMenu(-1);
|
|
}, 96);
|
|
|
|
app.ui.KeyHandler.addSingleCallback('KeyQ', function (e) {
|
|
if (app.ui.InteractionHandler.on) return;
|
|
e.preventDefault();
|
|
app.fireEvent('RequestDeselect');
|
|
}, 113);
|
|
|
|
|
|
app.ui.KeyHandler.addCallback('kF12', function (k, i, e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
}, [123]);
|
|
/*app.ui.KeyHandler.addCallback ('kF5', function ( k, i, e ) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
}, [116]);
|
|
*/
|
|
|
|
app.ui.KeyHandler.addCallback('KeyShiftSpace' + app.id, function (key) {
|
|
if (app.ui.InteractionHandler.on) return;
|
|
wavesurfer.playPause();
|
|
}, [16, 32]);
|
|
app.ui.KeyHandler.addCallback('KeySpace' + app.id, function (key, map) {
|
|
if (app.ui.InteractionHandler.on) return;
|
|
if (map[16] === 1) return;
|
|
|
|
if (PKAudioEditor.engine.wavesurfer.isPlaying()) {
|
|
app.fireEvent('RequestStop');
|
|
}
|
|
else {
|
|
app.fireEvent('RequestPlay');
|
|
}
|
|
}, [32]);
|
|
app.ui.KeyHandler.addCallback('KeyShiftCopy' + app.id, function (key) {
|
|
if (app.ui.InteractionHandler.on) return;
|
|
|
|
app.fireEvent('RequestActionCopy');
|
|
}, [16, 67]);
|
|
app.ui.KeyHandler.addCallback('KeyShiftUndo' + app.id, function (key) {
|
|
if (app.ui.InteractionHandler.on) return;
|
|
|
|
app.fireEvent('StateRequestUndo');
|
|
}, [16, 90]);
|
|
app.ui.KeyHandler.addCallback('KeyShiftRedo' + app.id, function (key) {
|
|
if (app.ui.InteractionHandler.on) return;
|
|
|
|
app.fireEvent('StateRequestRedo');
|
|
}, [16, 89]);
|
|
app.ui.KeyHandler.addCallback('KeyShiftPaste' + app.id, function (key) {
|
|
if (app.ui.InteractionHandler.on) return;
|
|
|
|
app.fireEvent('RequestActionPaste');
|
|
}, [16, 86]);
|
|
app.ui.KeyHandler.addCallback('KeyShiftCut' + app.id, function (key) {
|
|
if (app.ui.InteractionHandler.on) return;
|
|
|
|
app.fireEvent('RequestActionCut', 1);
|
|
}, [16, 88]);
|
|
app.ui.KeyHandler.addCallback('KeyDel' + app.id, function (key) {
|
|
if (app.ui.InteractionHandler.on) return;
|
|
|
|
app.fireEvent('RequestActionCut');
|
|
}, [8]);
|
|
app.ui.KeyHandler.addCallback('KeyShiftSelectAll' + app.id, function (key) {
|
|
if (app.ui.InteractionHandler.on) return;
|
|
app.fireEvent('RequestSelect');
|
|
}, [16, 65]);
|
|
app.ui.KeyHandler.addSingleCallback('KeyLoopToggle', function (e) {
|
|
if (app.ui.InteractionHandler.on) return;
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
app.fireEvent('RequestSetLoop');
|
|
}, 108);
|
|
app.ui.KeyHandler.addCallback('KeyShiftSave' + app.id, function (key) {
|
|
if (app.ui.InteractionHandler.on) return;
|
|
|
|
// fire event to open the save menu
|
|
document.querySelector('.pk_opt[data-id="dl"]').click();
|
|
}, [16, 83]);
|
|
|
|
wavesurfer.container.addEventListener('mousedown', function (e) {
|
|
if (e.which === 3) {
|
|
// wavesurfer.regions.clear();
|
|
e.preventDefault();
|
|
}
|
|
}, false);
|
|
|
|
// select all... ####
|
|
app.listenFor('RequestSelect', function (ifnot, custom) {
|
|
if (!q.is_ready) return;
|
|
|
|
if (ifnot) {
|
|
var region = wavesurfer.regions.list[0];
|
|
if (region) return (false);
|
|
}
|
|
|
|
if (!custom) {
|
|
wavesurfer.regions.add({
|
|
start: 0.000,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
|
|
if (!wavesurfer.isPlaying())
|
|
setTimeout(function () {
|
|
app.fireEvent('RequestSeekTo', 0.00);
|
|
}, 0);
|
|
}
|
|
else {
|
|
wavesurfer.regions.add({
|
|
start: custom[0],
|
|
end: custom[1],
|
|
id: 't'
|
|
});
|
|
if (!wavesurfer.isPlaying())
|
|
setTimeout(function () {
|
|
app.fireEvent('RequestSeekTo', custom[0] / wavesurfer.getDuration());
|
|
}, 0);
|
|
}
|
|
});
|
|
app.listenFor('RequestDeselect', function () {
|
|
wavesurfer.regions.clear();
|
|
app.fireEvent('RequestSeekTo', 0);
|
|
});
|
|
|
|
(function () {
|
|
var input = null;
|
|
app.listenFor('RequestLoadLocalFile', function () {
|
|
wavesurfer.pause();
|
|
|
|
if (input) {
|
|
input.parentNode.removeChild(input);
|
|
input.onchange = null;
|
|
}
|
|
|
|
input = d.createElement('input');
|
|
input.setAttribute('type', 'file');
|
|
input.setAttribute('accept', 'audio/*');
|
|
input.className = 'pk_inpfile';
|
|
input.onchange = function () {
|
|
q.LoadFile(input);
|
|
|
|
input.parentNode.removeChild(input);
|
|
input.onchange = null;
|
|
input = null;
|
|
};
|
|
app.el.appendChild(input); // maybe not append?
|
|
|
|
input.click();
|
|
});
|
|
})();
|
|
|
|
wavesurfer.container.addEventListener('dblclick', function (e) {
|
|
app.fireEvent('RequestSelect', false,
|
|
[wavesurfer.LeftProgress,
|
|
wavesurfer.LeftProgress + wavesurfer.VisibleDuration]
|
|
);
|
|
}, false);
|
|
wavesurfer.container.addEventListener('click', function (e) {
|
|
if (!q.is_ready) return;
|
|
|
|
if (!app.ui.KeyHandler.keyMap[16])
|
|
wavesurfer.regions.clear();
|
|
}, false);
|
|
|
|
var dbncr = null;
|
|
w.addEventListener('resize', function () {
|
|
if (!wavesurfer) return;
|
|
|
|
if (dbncr) {
|
|
clearTimeout(dbncr);
|
|
}
|
|
|
|
dbncr = setTimeout(function () {
|
|
|
|
//requestAnimationFrame(function (){
|
|
app.fireEvent('RequestResize');
|
|
|
|
if (app.isMobile) {
|
|
window.scrollTo(0, 200);
|
|
}
|
|
//});
|
|
}, 84);
|
|
}, false);
|
|
|
|
// w.addEventListener ('orientationchange', function () {
|
|
// app.fireEvent ('RequestResize');
|
|
// });
|
|
|
|
w.addEventListener('beforeunload', function (e) {
|
|
app.fireEvent('WillUnload');
|
|
|
|
// e.preventDefault();
|
|
// e.returnValue = '';
|
|
});
|
|
|
|
wavesurfer.on('error', function (error_msg) {
|
|
|
|
// if loading - cancel loading
|
|
setTimeout(function () {
|
|
app.fireEvent('DidDownloadFile'); // just hides the interface
|
|
q.is_ready = false;
|
|
}, 20);
|
|
|
|
app.fireEvent('ShowError', error_msg);
|
|
});
|
|
|
|
wavesurfer.on('audioprocess', function (time, stamp) {
|
|
// var time = wavesurfer.getCurrentTime();
|
|
var loudness = wavesurfer.getLoudness();
|
|
|
|
app.fireEvent('DidAudioProcess', [time, loudness, stamp], wavesurfer.backend.FreqArr);
|
|
});
|
|
wavesurfer.on('DidZoom', function (e) {
|
|
app.fireEvent('DidZoom', [wavesurfer.ZoomFactor, (wavesurfer.LeftProgress / wavesurfer.getDuration()) * 100, wavesurfer.params.verticalZoom], e);
|
|
});
|
|
wavesurfer.on('region-removed', function () {
|
|
app.fireEvent('DidSetLoop', 0);
|
|
app.fireEvent('DidDestroyRegion');
|
|
});
|
|
app.listenFor('RequestRegionClear', function () {
|
|
wavesurfer.regions.clear();
|
|
});
|
|
app.listenFor('RequestRegionSet', function (start, end) {
|
|
if (!q.is_ready) return;
|
|
|
|
if (!start) {
|
|
start = wavesurfer.LeftProgress / 1;
|
|
}
|
|
if (!end) {
|
|
end = (wavesurfer.LeftProgress + wavesurfer.VisibleDuration) / 1;
|
|
}
|
|
|
|
// add a region where the paste happened
|
|
wavesurfer.regions.clear();
|
|
wavesurfer.regions.add({
|
|
start: start,
|
|
end: end,
|
|
id: 't'
|
|
});
|
|
});
|
|
|
|
var copy_buffer = null;
|
|
|
|
this.GetCopyBuff = function () {
|
|
return (copy_buffer);
|
|
};
|
|
|
|
this.GetSel = function () {
|
|
var region = wavesurfer.regions.list[0];
|
|
if (!region) return (false);
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
var copybuffer = AudioUtils.Copy(
|
|
start,
|
|
end
|
|
);
|
|
|
|
return (copybuffer);
|
|
};
|
|
|
|
this.PlayBuff = function (buff_arr, chans, sample_rate, aud_cont) {
|
|
var audio_ctx;
|
|
|
|
if (aud_cont) audio_ctx = aud_cont;
|
|
else audio_ctx = new (w.AudioContext || w.webkitAudioContext)();
|
|
|
|
if (!audio_ctx) return;
|
|
|
|
var bytes = buff_arr[0].byteLength / 4;
|
|
|
|
var buffer = audio_ctx.createBuffer(
|
|
chans,
|
|
bytes,
|
|
sample_rate
|
|
);
|
|
|
|
for (var i = 0; i < chans; ++i) {
|
|
buffer.getChannelData(i).set(
|
|
new Float32Array(buff_arr[i])
|
|
);
|
|
}
|
|
|
|
var source = audio_ctx.createBufferSource();
|
|
source.buffer = buffer;
|
|
|
|
source.connect(audio_ctx.destination);
|
|
source.start(0);
|
|
|
|
return (source);
|
|
};
|
|
|
|
this.GetFX = function (fx, val) {
|
|
return AudioUtils.FXBank[fx](val);
|
|
};
|
|
|
|
this.GetWave = function (buffer, ww, hh, offset, llen, cnv, cx) {
|
|
var chan_data = buffer.getChannelData(0);
|
|
var sample_rate = buffer.sampleRate;
|
|
|
|
var peaks = [];
|
|
var curr_time = 0;
|
|
var width = ww || 200;
|
|
var height = hh || 80;
|
|
var half_height = (height / 2);
|
|
var new_width = width;
|
|
var pixels = 0;
|
|
var raw_pixels = 0;
|
|
|
|
var start_offset = offset || 0;
|
|
var end_offset = llen || ((buffer.duration * sample_rate) >> 0);
|
|
var length = end_offset - start_offset;
|
|
var mod = (length / width) >> 0;
|
|
|
|
var max = 0;
|
|
var min = 0;
|
|
|
|
for (var i = 0; i < new_width; ++i) {
|
|
var new_offset = start_offset + (mod * i);
|
|
|
|
max = 0;
|
|
min = 0;
|
|
|
|
if (new_offset >= 0) {
|
|
for (var j = 0; j < mod; j += 3) {
|
|
if (chan_data[new_offset + j] > max) {
|
|
max = chan_data[new_offset + j];
|
|
}
|
|
else if (chan_data[new_offset + j] < min) {
|
|
min = chan_data[new_offset + j];
|
|
}
|
|
}
|
|
}
|
|
|
|
peaks[2 * i] = max;
|
|
peaks[2 * i + 1] = min;
|
|
}
|
|
|
|
var canvas = cnv;
|
|
var ctx = cx;
|
|
|
|
if (!canvas) {
|
|
canvas = document.createElement('canvas');
|
|
canvas.width = width;
|
|
canvas.height = height;
|
|
|
|
ctx = canvas.getContext('2d', { alpha: false, antialias: false });
|
|
}
|
|
|
|
ctx.fillStyle = "#000";
|
|
ctx.fillRect(0, 0, width, height);
|
|
ctx.fillStyle = '#99c2c6';
|
|
|
|
ctx.beginPath();
|
|
ctx.moveTo(0, half_height);
|
|
|
|
for (var i = 0; i < width; ++i) {
|
|
var peak = peaks[i * 2];
|
|
var _h = Math.round(peak * half_height);
|
|
ctx.lineTo(i, half_height - _h);
|
|
}
|
|
|
|
for (var i = width - 1; i >= 0; --i) {
|
|
var peak = peaks[(i * 2) + 1];
|
|
var _h = Math.round(peak * half_height);
|
|
ctx.lineTo(i, half_height - _h);
|
|
}
|
|
|
|
ctx.closePath();
|
|
ctx.fill();
|
|
|
|
return (canvas.toDataURL('image/jpeg', 0.56));
|
|
// ---
|
|
};
|
|
|
|
app.listenFor('RequestActionCut', function (use_clipboard) {
|
|
if (!q.is_ready) return;
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
if (!region) return (false);
|
|
|
|
app.fireEvent('RequestPause');
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3)
|
|
|
|
app.fireEvent('StateRequestPush', {
|
|
desc: use_clipboard ? 'Cut' : 'Delete',
|
|
meta: [start, end],
|
|
data: wavesurfer.backend.buffer
|
|
});
|
|
|
|
var cutbuffer = AudioUtils.Trim(
|
|
start,
|
|
end
|
|
);
|
|
wavesurfer.regions.clear();
|
|
|
|
var tmp = (start - 0.03);
|
|
if (tmp < 0) tmp = 0;
|
|
|
|
app.fireEvent('RequestSeekTo', tmp / wavesurfer.getDuration());
|
|
|
|
if (use_clipboard) {
|
|
copy_buffer = cutbuffer;
|
|
|
|
app.fireEvent('DidSetClipboard', 1);
|
|
app.fireEvent('DidCut', cutbuffer);
|
|
|
|
OneUp('Cut :: ' + q.TrimTo(start, 2) + ' to ' + q.TrimTo(start / 1 + end / 1, 2), 1100);
|
|
}
|
|
else {
|
|
OneUp('Delete :: ' + q.TrimTo(start, 2) + ' to ' + q.TrimTo(start / 1 + end / 1, 2), 1100);
|
|
}
|
|
|
|
/*
|
|
var image = app.engine.GetWave (copy_buffer);
|
|
var eel = document.getElementsByClassName('pk_tb')[0];
|
|
var imm = new Image();
|
|
imm.src = image;
|
|
eel.appendChild( imm );
|
|
*/
|
|
});
|
|
|
|
app.listenFor('RequestActionCopy', function () {
|
|
if (!q.is_ready) return;
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
if (!region) return (false);
|
|
|
|
app.fireEvent('RequestPause');
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
var copybuffer = AudioUtils.Copy(
|
|
start,
|
|
end
|
|
);
|
|
|
|
copy_buffer = copybuffer;
|
|
app.fireEvent('DidSetClipboard', 1);
|
|
app.fireEvent('DidCopy', copybuffer);
|
|
|
|
OneUp('Copied range');
|
|
});
|
|
|
|
app.listenFor('RequestActionSilence', function (offset, silence_duration) {
|
|
if (!q.is_ready) return;
|
|
|
|
app.fireEvent('RequestPause');
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
if (!silence_duration || silence_duration < 0) silence_duration = 1;
|
|
|
|
function handleStateInline(start, end) {
|
|
app.fireEvent('StateRequestPush', {
|
|
desc: 'Silence',
|
|
meta: [start, end],
|
|
data: wavesurfer.backend.buffer
|
|
});
|
|
}
|
|
|
|
var start = offset;
|
|
var end = silence_duration;
|
|
|
|
handleStateInline(start, end);
|
|
dims = AudioUtils.Insert(
|
|
offset,
|
|
AudioUtils.MakeSilence(silence_duration)
|
|
);
|
|
|
|
// add a region where the paste happened
|
|
wavesurfer.regions.clear();
|
|
wavesurfer.regions.add({
|
|
start: dims[0],
|
|
end: dims[1],
|
|
id: 't'
|
|
});
|
|
|
|
app.fireEvent('RequestSeekTo', (dims[0] / wavesurfer.getDuration()));
|
|
|
|
OneUp('Inserted Silence');
|
|
});
|
|
|
|
app.listenFor('RequestActionPaste', function () {
|
|
if (!q.is_ready) return;
|
|
if (!copy_buffer) return (false);
|
|
|
|
app.fireEvent('RequestPause');
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
function handleStateInline(start, end) {
|
|
app.fireEvent('StateRequestPush', {
|
|
desc: 'Paste',
|
|
meta: [start, end],
|
|
data: wavesurfer.backend.buffer
|
|
});
|
|
}
|
|
|
|
if (!region) {
|
|
var offset = q.TrimTo(wavesurfer.getCurrentTime(), 3);
|
|
|
|
handleStateInline(offset);
|
|
dims = AudioUtils.Insert(offset, copy_buffer);
|
|
}
|
|
else {
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
handleStateInline(start, end);
|
|
|
|
dims = AudioUtils.Replace(
|
|
start,
|
|
end,
|
|
copy_buffer
|
|
);
|
|
}
|
|
|
|
// add a region where the paste happened
|
|
wavesurfer.regions.clear();
|
|
wavesurfer.regions.add({
|
|
start: dims[0],
|
|
end: dims[1],
|
|
id: 't'
|
|
});
|
|
|
|
var new_seek = 0;
|
|
if (wavesurfer.getDuration() > 0.0001) {
|
|
new_seek = dims[0] / wavesurfer.getDuration();
|
|
}
|
|
app.fireEvent('RequestSeekTo', new_seek);
|
|
|
|
OneUp('Paste to ' + dims[0].toFixed(2), 982);
|
|
});
|
|
|
|
var _sk = false;
|
|
app.listenFor('RequestActionRecordToggle', function () {
|
|
if (!q.is_ready) {
|
|
// if not ready then bring up the new recording toggle!
|
|
app.fireEvent('RequestActionNewRec');
|
|
|
|
return;
|
|
}
|
|
|
|
if (app.rec.isActive()) {
|
|
app.fireEvent('RequestActionRecordStop');
|
|
} else {
|
|
// skipping the sounds of keyboard
|
|
if (_sk) return;
|
|
|
|
_sk = true;
|
|
setTimeout(function () {
|
|
app.fireEvent('RequestActionRecordStart');
|
|
setTimeout(function () {
|
|
_sk = false;
|
|
}, 50);
|
|
}, 26);
|
|
}
|
|
});
|
|
|
|
app.listenFor('RequestActionRecordStop', function () {
|
|
if (!q.is_ready) return;
|
|
if (!app.rec.isActive()) return (false);
|
|
|
|
app.rec.stop();
|
|
});
|
|
|
|
app.listenFor('RequestActionRecordStart', function () {
|
|
if (!q.is_ready) return;
|
|
|
|
app.fireEvent('RequestPause');
|
|
|
|
if (app.rec.isActive()) return (false);
|
|
|
|
var pos = wavesurfer.getCurrentTime() * wavesurfer.backend.buffer.sampleRate;
|
|
app.rec.start(pos, function (offset, buffers) {
|
|
|
|
// app.fireEvent ('RequestPause');
|
|
function handleStateInline(start, end) {
|
|
app.fireEvent('StateRequestPush', {
|
|
desc: 'Record Audio',
|
|
meta: [start, end],
|
|
data: wavesurfer.backend.buffer
|
|
});
|
|
}
|
|
|
|
// fire did record event!
|
|
app.fireEvent('DidActionRecordStop', !!buffers);
|
|
if (!buffers) {
|
|
return;
|
|
}
|
|
|
|
handleStateInline(offset);
|
|
var dims = AudioUtils.ReplaceFloatArrays(offset, buffers);
|
|
|
|
// add a region where the paste happened
|
|
wavesurfer.regions.clear();
|
|
wavesurfer.regions.add({
|
|
start: dims[0],
|
|
end: dims[1],
|
|
id: 't'
|
|
});
|
|
|
|
app.fireEvent('RequestSeekTo', (dims[0] / wavesurfer.getDuration()));
|
|
OneUp('Recorded Audio ' + dims[0].toFixed(2), 982);
|
|
}, function () {
|
|
// on start
|
|
app.fireEvent('DidActionRecordStart');
|
|
});
|
|
|
|
// --- ending offset is song full duration...
|
|
// if we have a selected area - mark that one as the end
|
|
var region = wavesurfer.regions.list[0];
|
|
if (region)
|
|
app.rec.setEndingOffset(region.end * wavesurfer.backend.buffer.sampleRate);
|
|
else
|
|
app.rec.setEndingOffset(wavesurfer.getDuration() * wavesurfer.backend.buffer.sampleRate);
|
|
});
|
|
|
|
app.listenFor('RequestActionFX_PREVIEW_HardLimit', function (val) {
|
|
if (!q.is_ready) return;
|
|
if (AudioUtils.previewing) {
|
|
AudioUtils.FXPreviewStop();
|
|
app.fireEvent('DidStopPreview');
|
|
return;
|
|
}
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
AudioUtils.FXPreview(start, end, AudioUtils.FXBank.HardLimit(val));
|
|
app.fireEvent('DidStartPreview');
|
|
});
|
|
app.listenFor('RequestActionFX_HardLimit', function (val) {
|
|
if (!q.is_ready) return;
|
|
|
|
app.fireEvent('RequestPause');
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
function handleStateInline(start, end) {
|
|
app.fireEvent('StateRequestPush', {
|
|
desc: 'Apply Hard Limit (fx)',
|
|
meta: [start, end],
|
|
data: wavesurfer.backend.buffer
|
|
});
|
|
}
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
handleStateInline(start, end);
|
|
AudioUtils.FX(start, end, AudioUtils.FXBank.HardLimit(val));
|
|
|
|
OneUp('Applied Hard Limit (fx)');
|
|
});
|
|
|
|
app.listenFor('RequestActionFX_PARAMEQ', function (val) {
|
|
if (!q.is_ready) return;
|
|
|
|
app.fireEvent('RequestPause');
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
function handleStateInline(start, end) {
|
|
app.fireEvent('StateRequestPush', {
|
|
desc: 'Apply Parametric EQ (fx)',
|
|
meta: [start, end],
|
|
data: wavesurfer.backend.buffer
|
|
});
|
|
}
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
handleStateInline(start, end);
|
|
AudioUtils.FX(start, end, AudioUtils.FXBank.ParametricEQ(val));
|
|
|
|
OneUp('Applied Parametric EQ (fx)');
|
|
});
|
|
app.listenFor('RequestActionFX_PREVIEW_PARAMEQ', function (val) {
|
|
if (!q.is_ready || !val) return;
|
|
if (AudioUtils.previewing) {
|
|
AudioUtils.FXPreviewStop();
|
|
app.fireEvent('DidStopPreview');
|
|
return;
|
|
}
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
AudioUtils.FXPreview(start, end, AudioUtils.FXBank.ParametricEQ(val));
|
|
app.fireEvent('DidStartPreview');
|
|
});
|
|
|
|
app.listenFor('RequestActionFX_PREVIEW_DISTORT', function (val) {
|
|
if (!q.is_ready) return;
|
|
if (AudioUtils.previewing) {
|
|
AudioUtils.FXPreviewStop();
|
|
app.fireEvent('DidStopPreview');
|
|
return;
|
|
}
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
AudioUtils.FXPreview(start, end, AudioUtils.FXBank.Distortion(val));
|
|
app.fireEvent('DidStartPreview');
|
|
});
|
|
app.listenFor('RequestActionFX_DISTORT', function (val) {
|
|
if (!q.is_ready) return;
|
|
|
|
app.fireEvent('RequestPause');
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
function handleStateInline(start, end) {
|
|
app.fireEvent('StateRequestPush', {
|
|
desc: 'Apply Distortion (fx)',
|
|
meta: [start, end],
|
|
data: wavesurfer.backend.buffer
|
|
});
|
|
}
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
handleStateInline(start, end);
|
|
AudioUtils.FX(start, end, AudioUtils.FXBank.Distortion(val));
|
|
|
|
OneUp('Applied Distortion (fx)');
|
|
});
|
|
|
|
app.listenFor('RequestActionFX_PREVIEW_DELAY', function (val) {
|
|
if (!q.is_ready) return;
|
|
if (AudioUtils.previewing) {
|
|
AudioUtils.FXPreviewStop();
|
|
app.fireEvent('DidStopPreview');
|
|
return;
|
|
}
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
AudioUtils.FXPreview(start, end, AudioUtils.FXBank.Delay(val));
|
|
app.fireEvent('DidStartPreview');
|
|
});
|
|
app.listenFor('RequestActionFX_DELAY', function (val) {
|
|
if (!q.is_ready) return;
|
|
|
|
app.fireEvent('RequestPause');
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
function handleStateInline(start, end) {
|
|
app.fireEvent('StateRequestPush', {
|
|
desc: 'Apply Delay (fx)',
|
|
meta: [start, end],
|
|
data: wavesurfer.backend.buffer
|
|
});
|
|
}
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
handleStateInline(start, end);
|
|
AudioUtils.FX(start, end, AudioUtils.FXBank.Delay(val));
|
|
|
|
OneUp('Applied Delay (fx)');
|
|
});
|
|
|
|
app.listenFor('RequestActionFX_PREVIEW_REVERB', function (val) {
|
|
if (!q.is_ready) return;
|
|
if (AudioUtils.previewing) {
|
|
AudioUtils.FXPreviewStop();
|
|
app.fireEvent('DidStopPreview');
|
|
return;
|
|
}
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
AudioUtils.FXPreview(start, end, AudioUtils.FXBank.Reverb(val));
|
|
app.fireEvent('DidStartPreview');
|
|
});
|
|
app.listenFor('RequestActionFX_REVERB', function (val) {
|
|
if (!q.is_ready) return;
|
|
|
|
app.fireEvent('RequestPause');
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
function handleStateInline(start, end) {
|
|
app.fireEvent('StateRequestPush', {
|
|
desc: 'Apply Reverb (fx)',
|
|
meta: [start, end],
|
|
data: wavesurfer.backend.buffer
|
|
});
|
|
}
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
handleStateInline(start, end);
|
|
AudioUtils.FX(start, end, AudioUtils.FXBank.Reverb(val));
|
|
|
|
OneUp('Applied Reverb (fx)');
|
|
});
|
|
|
|
app.listenFor('RequestActionFX_PREVIEW_COMPRESSOR', function (val) {
|
|
if (!q.is_ready) return;
|
|
if (AudioUtils.previewing) {
|
|
AudioUtils.FXPreviewStop();
|
|
app.fireEvent('DidStopPreview');
|
|
return;
|
|
}
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
AudioUtils.FXPreview(start, end, AudioUtils.FXBank.Compressor(val));
|
|
app.fireEvent('DidStartPreview');
|
|
});
|
|
|
|
app.listenFor('RequestActionFX_Compressor', function (val) {
|
|
if (!q.is_ready) return;
|
|
|
|
app.fireEvent('RequestPause');
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
function handleStateInline(start, end) {
|
|
app.fireEvent('StateRequestPush', {
|
|
desc: 'Apply Compressor (fx)',
|
|
meta: [start, end],
|
|
data: wavesurfer.backend.buffer
|
|
});
|
|
}
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
handleStateInline(start, end);
|
|
AudioUtils.FX(start, end, AudioUtils.FXBank.Compressor(val));
|
|
|
|
OneUp('Applied Compressor (fx)');
|
|
});
|
|
app.listenFor('RequestActionFX_Normalize', function (val) {
|
|
if (!q.is_ready) return;
|
|
|
|
app.fireEvent('RequestPause');
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
function handleStateInline(start, end) {
|
|
app.fireEvent('StateRequestPush', {
|
|
desc: 'Normalize ',
|
|
meta: [start, end],
|
|
data: wavesurfer.backend.buffer
|
|
});
|
|
}
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3)
|
|
var end = q.TrimTo((region.end - region.start), 3)
|
|
|
|
handleStateInline(start, end);
|
|
AudioUtils.FX(start, end, AudioUtils.FXBank.Normalize(val));
|
|
|
|
OneUp('Applied Normalize');
|
|
});
|
|
|
|
app.listenFor('RequestActionFX_Invert', function (val) {
|
|
if (!q.is_ready) return;
|
|
|
|
app.fireEvent('RequestPause');
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
function handleStateInline(start, end) {
|
|
app.fireEvent('StateRequestPush', {
|
|
desc: 'Invert ',
|
|
meta: [start, end],
|
|
data: wavesurfer.backend.buffer
|
|
});
|
|
}
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3)
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
handleStateInline(start, end);
|
|
AudioUtils.FX(start, end, AudioUtils.FXBank.Invert());
|
|
|
|
OneUp('Applied Invert');
|
|
});
|
|
|
|
app.listenFor('RequestActionFX_RemSil', function (val) {
|
|
if (!q.is_ready) return;
|
|
|
|
app.fireEvent('RequestPause');
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
function handleStateInline(start, end) {
|
|
app.fireEvent('StateRequestPush', {
|
|
desc: 'Remove Silence ',
|
|
meta: [start, end],
|
|
data: wavesurfer.backend.buffer
|
|
});
|
|
}
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3)
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
handleStateInline(start, end);
|
|
|
|
var originalBuffer = wavesurfer.backend.buffer;
|
|
var sil_arr = [];
|
|
var sil_offset = 210;
|
|
var vol_offset = 56;
|
|
var count = 0;
|
|
var inv_count = 0;
|
|
var start = 0;
|
|
var end = 0;
|
|
var found = false;
|
|
var jump = 500;
|
|
|
|
for (var i = 0; i < 1; ++i) {
|
|
var channel = originalBuffer.getChannelData(i);
|
|
|
|
for (var j = 0; j < channel.length; ++j) {
|
|
if (Math.abs(channel[j]) < 0.000368) {
|
|
if (count === 0) {
|
|
|
|
if (j > jump)
|
|
start = j - jump;
|
|
else
|
|
start = j;
|
|
}
|
|
if (++count > sil_offset) {
|
|
inv_count = 0;
|
|
end = j;
|
|
found = true;
|
|
}
|
|
}
|
|
else {
|
|
if (found) {
|
|
if (++inv_count > vol_offset) {
|
|
sil_arr.push([start, end]);
|
|
j += jump;
|
|
|
|
count = 0;
|
|
start = 0;
|
|
end = 0;
|
|
found = false;
|
|
inv_count = 0;
|
|
}
|
|
else {
|
|
end = j;
|
|
}
|
|
}
|
|
else {
|
|
count = 0;
|
|
start = 0;
|
|
end = 0;
|
|
found = false;
|
|
inv_count = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (found) {
|
|
sil_arr.push([start, end]);
|
|
}
|
|
}
|
|
|
|
if (sil_arr.length > 0) {
|
|
var reduce = 0;
|
|
for (var i = 0; i < sil_arr.length; ++i) {
|
|
reduce += (sil_arr[i][1] - sil_arr[i][0]);
|
|
}
|
|
|
|
var emptySegment = wavesurfer.backend.ac.createBuffer(
|
|
originalBuffer.numberOfChannels,
|
|
originalBuffer.length - reduce,
|
|
originalBuffer.sampleRate
|
|
);
|
|
|
|
for (var i = 0; i < originalBuffer.numberOfChannels; ++i) {
|
|
var channel = originalBuffer.getChannelData(i);
|
|
var new_channel = emptySegment.getChannelData(i);
|
|
|
|
var sil_offset = 0;
|
|
var o = 0;
|
|
var sil_curr = sil_arr[o];
|
|
var sil_curr_start = sil_curr[0];
|
|
var sil_curr_end = sil_curr[1];
|
|
var h = 0;
|
|
var use_old = false;
|
|
var old_h = 0;
|
|
|
|
for (var j = 0; j < new_channel.length; ++j) {
|
|
h = j + sil_offset;
|
|
if (h > sil_curr_start && h < sil_curr_end) {
|
|
if (h < sil_curr_start + jump) {
|
|
var perc = (jump - (h - sil_curr_start)) / jump;
|
|
new_channel[j] = (channel[h] * perc); // / (h - sil_curr_start));
|
|
new_channel[j] += (1 - perc) * channel[j + (sil_offset + (sil_curr_end - sil_curr_start))];
|
|
|
|
continue;
|
|
}
|
|
else {
|
|
sil_offset = sil_offset + (sil_curr_end - sil_curr_start);
|
|
sil_curr = sil_arr[++o];
|
|
if (sil_curr) {
|
|
sil_curr_start = sil_curr[0];
|
|
sil_curr_end = sil_curr[1];
|
|
}
|
|
h = j + sil_offset;
|
|
}
|
|
}
|
|
|
|
new_channel[j] = channel[h];
|
|
}
|
|
}
|
|
|
|
AudioUtils.FullReplace(
|
|
emptySegment
|
|
);
|
|
}
|
|
|
|
setTimeout(function () {
|
|
wavesurfer.drawBuffer();
|
|
}, 40);
|
|
|
|
OneUp('Applied :: Remove Silence');
|
|
});
|
|
|
|
|
|
var _compute_channels = function () {
|
|
var buff = wavesurfer.backend.buffer;
|
|
var chans = buff.numberOfChannels;
|
|
|
|
if (chans === 1) {
|
|
wavesurfer.ActiveChannels = [1];
|
|
app.el.classList.add('pk_mono');
|
|
}
|
|
else {
|
|
wavesurfer.ActiveChannels = [1, 1];
|
|
app.el.classList.remove('pk_mono');
|
|
}
|
|
|
|
wavesurfer.drawer.params.ActiveChannels = wavesurfer.ActiveChannels;
|
|
wavesurfer.SelectedChannelsLen = chans;
|
|
};
|
|
|
|
app.listenFor('RequestActionFX_Flip', function (val, val2) {
|
|
if (!q.is_ready) return;
|
|
|
|
app.fireEvent('RequestPause');
|
|
|
|
var start = 0;
|
|
var end = wavesurfer.getDuration();
|
|
|
|
function handleStateInline(start, end, title, cb) {
|
|
app.fireEvent('StateRequestPush', {
|
|
desc: title,
|
|
meta: [start, end],
|
|
data: wavesurfer.backend.buffer,
|
|
cb: cb
|
|
});
|
|
}
|
|
|
|
if (val === 'flip') {
|
|
handleStateInline(start, end, 'Flip Channels');
|
|
AudioUtils.FX(start, end, AudioUtils.FXBank.Flip(val));
|
|
}
|
|
else if (val === 'stereo') {
|
|
handleStateInline(start, end, 'Make Stereo', function () { _compute_channels() });
|
|
|
|
var originalBuffer = wavesurfer.backend.buffer;
|
|
var emptySegment = wavesurfer.backend.ac.createBuffer(
|
|
2,
|
|
originalBuffer.length,
|
|
originalBuffer.sampleRate
|
|
);
|
|
emptySegment.getChannelData(0).set(
|
|
originalBuffer.getChannelData(0)
|
|
);
|
|
emptySegment.getChannelData(1).set(
|
|
originalBuffer.getChannelData(0)
|
|
);
|
|
|
|
AudioUtils.FullReplace(
|
|
emptySegment
|
|
);
|
|
|
|
wavesurfer.regions.clear();
|
|
wavesurfer.regions.add({
|
|
start: start,
|
|
end: end,
|
|
id: 't'
|
|
});
|
|
|
|
_compute_channels();
|
|
|
|
app.fireEvent('RequestSeekTo', 0.00);
|
|
}
|
|
else if (val === 'mono') {
|
|
handleStateInline(start, end, 'Make Mono', function () { _compute_channels() });
|
|
|
|
var originalBuffer = wavesurfer.backend.buffer;
|
|
var emptySegment = wavesurfer.backend.ac.createBuffer(
|
|
1,
|
|
originalBuffer.length,
|
|
originalBuffer.sampleRate
|
|
);
|
|
emptySegment.getChannelData(0).set(
|
|
originalBuffer.getChannelData(val2)
|
|
);
|
|
AudioUtils.FullReplace(
|
|
emptySegment
|
|
);
|
|
|
|
wavesurfer.regions.clear();
|
|
wavesurfer.regions.add({
|
|
start: start,
|
|
end: end,
|
|
id: 't'
|
|
});
|
|
|
|
_compute_channels();
|
|
|
|
app.fireEvent('RequestSeekTo', 0.00);
|
|
}
|
|
|
|
OneUp('Applied Channel Change: ' + val);
|
|
});
|
|
|
|
app.listenFor('RequestActionFX_Reverse', function (val) {
|
|
if (!q.is_ready) return;
|
|
|
|
app.fireEvent('RequestPause');
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
function handleStateInline(start, end) {
|
|
app.fireEvent('StateRequestPush', {
|
|
desc: 'Reverse ',
|
|
meta: [start, end],
|
|
data: wavesurfer.backend.buffer
|
|
});
|
|
}
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3)
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
handleStateInline(start, end);
|
|
AudioUtils.FX(start, end, AudioUtils.FXBank.Reverse());
|
|
|
|
OneUp('Applied Reverse');
|
|
});
|
|
|
|
var noisernn_load = !1;
|
|
app.listenFor("RequestActionFX_NoiseRNN", function (a) {
|
|
var h = wavesurfer;
|
|
if (q.is_ready) { // n -> q
|
|
app.fireEvent("RequestPause");
|
|
var b = function () {
|
|
var f = h.regions.list[0];
|
|
f || (h.regions.add({ start: 0, end: h.getDuration() - 0, id: "t" }), (f = h.regions.list[0]));
|
|
var m = q.TrimTo(f.start, 3),
|
|
k = q.TrimTo(f.end - f.start, 3);
|
|
f = f.end - f.start;
|
|
f = q.TrimTo(f, 3);
|
|
app.fireEvent("StateRequestPush", { desc: "Apply Noise RNN (fx)", meta: [m, k], data: h.backend.buffer });
|
|
for (var u = AudioUtils.Copy(m, k), w = 0; w < u.numberOfChannels; w++) {
|
|
var x = u.getChannelData(w),
|
|
z = wasm_denoise_stream_perf(x);
|
|
x.set(z);
|
|
}
|
|
AudioUtils.Replace(m, k, u);
|
|
app.fireEvent("RequestSeekTo", m / h.getDuration());
|
|
wavesurfer.regions.clear();
|
|
h.regions.add({ start: m, end: m + f, id: "t" });
|
|
OneUp("Applied Noise RNN (fx)");
|
|
};
|
|
noisernn_load
|
|
? b()
|
|
: ((a = document.createElement("script")),
|
|
(a.src = "rnn_denoise.js"),
|
|
(a.onload = function () {
|
|
noisernn_load = !0;
|
|
var f = function () {
|
|
window.Module && window.Module.asm && window.Module.asm.malloc
|
|
? b()
|
|
: setTimeout(function () {
|
|
f();
|
|
}, 350);
|
|
};
|
|
setTimeout(function () {
|
|
f();
|
|
}, 100);
|
|
}),
|
|
(a.onerror = function () {
|
|
alert("Could not download noise Reduction script");
|
|
}),
|
|
document.head.appendChild(a));
|
|
}
|
|
});
|
|
|
|
app.listenFor('RequestActionFX_FadeIn', function (val) {
|
|
if (!q.is_ready) return;
|
|
|
|
app.fireEvent('RequestPause');
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
function handleStateInline(start, end) {
|
|
app.fireEvent('StateRequestPush', {
|
|
desc: 'Apply Fade In (fx)',
|
|
meta: [start, end],
|
|
data: wavesurfer.backend.buffer
|
|
});
|
|
}
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
handleStateInline(start, end);
|
|
AudioUtils.FX(start, end, AudioUtils.FXBank.FadeIn());
|
|
|
|
OneUp('Applied Fade In (fx)');
|
|
});
|
|
app.listenFor('RequestActionFX_FadeOut', function (val) {
|
|
if (!q.is_ready) return;
|
|
|
|
app.fireEvent('RequestPause');
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
function handleStateInline(start, end) {
|
|
app.fireEvent('StateRequestPush', {
|
|
desc: 'Apply Fade Out (fx)',
|
|
meta: [start, end],
|
|
data: wavesurfer.backend.buffer
|
|
});
|
|
}
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
handleStateInline(start, end);
|
|
AudioUtils.FX(start, end, AudioUtils.FXBank.FadeOut());
|
|
|
|
OneUp('Applied Fade Out (fx)');
|
|
});
|
|
|
|
|
|
var fx_preview_debounce = null;
|
|
app.listenFor('RequestActionFX_UPDATE_PREVIEW', function (val) {
|
|
if (!AudioUtils.previewing) return;
|
|
|
|
clearTimeout(fx_preview_debounce);
|
|
fx_preview_debounce = setTimeout(function () {
|
|
AudioUtils.FXPreviewUpdate(val);
|
|
}, 44);
|
|
});
|
|
app.listenFor('RequestActionFX_TOGGLE', function (val) {
|
|
|
|
if (val) {
|
|
AudioUtils.FXPreviewInit(true);
|
|
return;
|
|
}
|
|
|
|
app.fireEvent('DidTogglePreview', AudioUtils.FXPreviewToggle());
|
|
});
|
|
app.listenFor('RequestActionFX_PREVIEW_STOP', function () {
|
|
AudioUtils.FXPreviewStop();
|
|
app.fireEvent('DidStopPreview');
|
|
});
|
|
app.listenFor('RequestActionFX_PREVIEW_GAIN', function (val) {
|
|
if (!q.is_ready) return;
|
|
if (AudioUtils.previewing) {
|
|
AudioUtils.FXPreviewStop();
|
|
app.fireEvent('DidStopPreview');
|
|
return;
|
|
}
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
AudioUtils.FXPreview(start, end, AudioUtils.FXBank.Gain(val));
|
|
|
|
app.fireEvent('DidStartPreview');
|
|
});
|
|
|
|
app.listenFor('RequestActionFX_GAIN', function (val) {
|
|
if (!q.is_ready) return;
|
|
|
|
app.fireEvent('RequestPause');
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
function handleStateInline(start, end) {
|
|
app.fireEvent('StateRequestPush', {
|
|
desc: 'Apply Gain (fx)',
|
|
meta: [start, end],
|
|
data: wavesurfer.backend.buffer
|
|
});
|
|
}
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
handleStateInline(start, end);
|
|
AudioUtils.FX(start, end, AudioUtils.FXBank.Gain(val));
|
|
|
|
OneUp('Applied Gain (fx)');
|
|
});
|
|
|
|
app.listenFor('RequestActionFX_PREVIEW_SPEED', function (val) {
|
|
if (!q.is_ready) return;
|
|
if (AudioUtils.previewing) {
|
|
AudioUtils.FXPreviewStop();
|
|
app.fireEvent('DidStopPreview');
|
|
return;
|
|
}
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
|
|
AudioUtils.FXPreview(start, end, AudioUtils.FXBank.Speed(val));
|
|
|
|
app.fireEvent('DidStartPreview');
|
|
});
|
|
|
|
app.listenFor('RequestActionFX_RATE', function (val) {
|
|
if (!q.is_ready) return;
|
|
|
|
app.fireEvent('RequestPause');
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
function handleStateInline(start, end) {
|
|
app.fireEvent('StateRequestPush', {
|
|
desc: 'Apply Rate (fx)',
|
|
meta: [start, end],
|
|
data: wavesurfer.backend.buffer
|
|
});
|
|
}
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
var duration = (region.end - region.start) / val;
|
|
duration = q.TrimTo(duration, 3);
|
|
|
|
handleStateInline(start, end);
|
|
|
|
var fx_buffer = AudioUtils.Copy(start, end);
|
|
var originalBuffer = wavesurfer.backend.buffer;
|
|
var new_offset = ((start / 1) * originalBuffer.sampleRate) >> 0;
|
|
var new_len = ((duration / 1) * originalBuffer.sampleRate) >> 0;
|
|
var old_len = ((end / 1) * originalBuffer.sampleRate) >> 0;
|
|
var stretch_ratio = new_len / old_len;
|
|
|
|
var getOfflineAudioContext = function (channels, sampleRate, duration) {
|
|
return new (window.OfflineAudioContext ||
|
|
window.webkitOfflineAudioContext)(channels, duration, sampleRate);
|
|
};
|
|
var audio_ctx = getOfflineAudioContext( // offlineCtx
|
|
wavesurfer.SelectedChannelsLen, // orig_buffer.numberOfChannels,
|
|
fx_buffer.sampleRate,
|
|
new_len
|
|
);
|
|
|
|
/*
|
|
var TimeStretcher = function(o){o=o||{};this.ws=o.windowSize||1024;this.or=o.overlapRatio||0.5;this.sw=o.seekWindowMs||30;}
|
|
TimeStretcher.prototype.stretch=function(buf,ts){
|
|
if(ts<=0) throw new Error("Stretch ratio must be positive");
|
|
var ch=buf.numberOfChannels, sr=buf.sampleRate, il=buf.length, ol=Math.floor(il*ts),
|
|
out=new AudioBuffer({numberOfChannels:ch,length:ol,sampleRate:sr});
|
|
for(var c=0;c<ch;c++){
|
|
var inD=buf.getChannelData(c), outD=out.getChannelData(c), ws=this.ws,
|
|
ov=Math.floor(ws*this.or), hs=ws-ov, sw=Math.floor(this.sw*sr/1000),
|
|
win=this._hannWindow(ws), iIdx=0, oIdx=0;
|
|
while(oIdx<ol-ws){
|
|
var nIdx=Math.min(Math.floor(oIdx/ts),il-ws-sw);
|
|
if(iIdx>0 && Math.abs(nIdx-iIdx)>hs){
|
|
var ssi=Math.max(0,nIdx-sw), sei=Math.min(il-ws,nIdx+sw);
|
|
iIdx=this._findBestMatch(inD,iIdx+hs,ssi,sei,ws);
|
|
} else { iIdx=nIdx; }
|
|
for(var i=0;i<ws;i++){
|
|
if(iIdx+i<il && oIdx+i<ol)
|
|
outD[oIdx+i]+= inD[iIdx+i]*win[i];
|
|
}
|
|
oIdx+=hs;
|
|
}
|
|
this._normalizeOutput(outD);
|
|
}
|
|
return out;
|
|
};
|
|
TimeStretcher.prototype._hannWindow=function(l){var w=new Float32Array(l);for(var i=0;i<l;i++)w[i]=0.5*(1-Math.cos(2*Math.PI*i/(l-1)));return w;};
|
|
TimeStretcher.prototype._findBestMatch=function(d,ref,s,e,ws){
|
|
var bp=s,be=Number.MAX_VALUE, refArr=new Float32Array(ws);
|
|
for(var i=0;i<ws;i++) if(ref+i<d.length) refArr[i]=d[ref+i];
|
|
for(var pos=s;pos<=e;pos++){
|
|
var err=0;
|
|
for(var i=0;i<ws;i+=4) {
|
|
if(pos+i<d.length){var diff=refArr[i]-d[pos+i];err+=diff*diff;}
|
|
}
|
|
if(err<be){be=err;bp=pos;}
|
|
}
|
|
return bp;
|
|
};
|
|
TimeStretcher.prototype._normalizeOutput=function(d){
|
|
var m=0; for(var i=0;i<d.length;i++) m=Math.max(m,Math.abs(d[i]));
|
|
if(m>1){var g=0.95/m; for(var i=0;i<d.length;i++) d[i]*=g;}
|
|
};*/
|
|
var stretchAudio = function (input_buffer, sampleRate, stretchRatio) {
|
|
// Parameters (in seconds)
|
|
let channels_len = input_buffer.numberOfChannels;
|
|
let samples = [input_buffer.getChannelData(0)];
|
|
for (let i = 1; i < channels_len; ++i) {
|
|
samples.push(input_buffer.getChannelData(i));
|
|
}
|
|
|
|
let grainDurationSec = 0.05; // 50 ms
|
|
const analysisHopSec = 0.025; // 25 ms (50% overlap)
|
|
const desiredOverlap = 0.5;
|
|
const synthesisHopSec = analysisHopSec * stretchRatio; // output hop
|
|
|
|
// Adjust grain duration for ratios > 1
|
|
if (stretchRatio > 1) {
|
|
grainDurationSec = synthesisHopSec / (1 - desiredOverlap);
|
|
}
|
|
|
|
// Convert durations to samples
|
|
const grainSize = Math.floor(grainDurationSec * sampleRate);
|
|
const analysisHop = Math.floor(analysisHopSec * sampleRate);
|
|
const synthesisHop = Math.floor(synthesisHopSec * sampleRate);
|
|
|
|
// Precompute Hann window
|
|
const window = new Float32Array(grainSize);
|
|
for (let i = 0; i < grainSize; i++) {
|
|
// Using (grainSize - 1) so that the window spans [0, grainDurationSec]
|
|
window[i] = 0.5 * (1 - Math.cos((2 * Math.PI * i) / (grainSize - 1)));
|
|
}
|
|
|
|
// Estimate number of grains and output length
|
|
const numGrains = Math.floor((samples[0].length - grainSize) / analysisHop);
|
|
const outputLength = synthesisHop * numGrains + grainSize;
|
|
let output = [new Float32Array(outputLength)];
|
|
for (let i = 1; i < channels_len; ++i) {
|
|
output.push(new Float32Array(outputLength));
|
|
}
|
|
|
|
// Process each grain: copy, window, and add to output
|
|
let inputIndex = 0;
|
|
let outputIndex = 0;
|
|
for (let n = 0; n < numGrains; ++n) {
|
|
// For each sample in the grain, multiply by the window and add to the output
|
|
for (let i = 0; i < grainSize; ++i) {
|
|
for (let j = 0; j < channels_len; ++j) {
|
|
output[j][outputIndex + i] += samples[j][inputIndex + i] * window[i];
|
|
}
|
|
}
|
|
inputIndex += analysisHop;
|
|
outputIndex += synthesisHop;
|
|
}
|
|
|
|
/*
|
|
let normalization = new Float32Array(outputLength);
|
|
inputIndex = 0;
|
|
outputIndex = 0;
|
|
for (let n = 0; n < numGrains; ++n) {
|
|
for (let i = 0; i < grainSize; ++i) {
|
|
normalization[outputIndex + i] += window[i];
|
|
}
|
|
inputIndex += analysisHop;
|
|
outputIndex += synthesisHop;
|
|
}
|
|
|
|
// Normalize each channel's output:
|
|
for (let j = 0; j < channels_len; ++j) {
|
|
for (let i = 0; i < outputLength; ++i) {
|
|
if (normalization[i] > 0) {
|
|
output[j][i] /= normalization[i];
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
return output;
|
|
};
|
|
|
|
/// -----
|
|
var filter = [];
|
|
//if (stretch_ratio < 1) {
|
|
// var fx = AudioUtils.FXBank.Rate( stretch_ratio );
|
|
// var source = {buffer:null, disconnect:function(){}};
|
|
// source.buffer = fx_buffer;
|
|
// filter = fx.filter ( audio_ctx, audio_ctx.destination, source, duration );
|
|
//}
|
|
//else
|
|
//{
|
|
// use timestretcher here...
|
|
// var ts = new TimeStretcher({windowSize:2048,overlapRatio:0.75,seekWindowMs:20}).stretch(fx_buffer,stretch_ratio);
|
|
const stretchedSamples = stretchAudio(fx_buffer, fx_buffer.sampleRate, stretch_ratio);
|
|
|
|
// Optionally, if you need an AudioBuffer from the stretchedSamples:
|
|
// const offlineCtx = new OfflineAudioContext(stretchedSamples.length, stretchedSamples[0].length, fx_buffer.sampleRate);
|
|
const newBuffer = audio_ctx.createBuffer(stretchedSamples.length, stretchedSamples[0].length, fx_buffer.sampleRate);
|
|
|
|
for (let i = 0; i < stretchedSamples.length; ++i) {
|
|
newBuffer.copyToChannel(stretchedSamples[i], i);
|
|
}
|
|
|
|
var source = audio_ctx.createBufferSource();
|
|
source.buffer = newBuffer;
|
|
source.connect(audio_ctx.destination);
|
|
source.start();
|
|
//}
|
|
|
|
q.in_fx = true;
|
|
app.ui.InteractionHandler.on = true;
|
|
// OneUp ('Please wait, applying FX', 2600);
|
|
|
|
var offline_callback = function (rendered_buffer) {
|
|
AudioUtils.Replace(start, end, rendered_buffer);
|
|
|
|
wavesurfer.regions.clear();
|
|
wavesurfer.regions.add({
|
|
start: start,
|
|
end: start + duration,
|
|
id: 't'
|
|
});
|
|
|
|
app.fireEvent('RequestSeekTo', (start / wavesurfer.getDuration()));
|
|
|
|
OneUp('Applied Rate (fx)');
|
|
|
|
if (filter.length > 0) {
|
|
for (var i = 0; i < filter.length; ++i) filter[i].disconnect();
|
|
} else filter && filter.disconnect && filter.disconnect();
|
|
|
|
rendered_buffer = fx_buffer = filter = null;
|
|
source.disconnect();
|
|
|
|
q.in_fx = false;
|
|
app.ui.InteractionHandler.on = false;
|
|
};
|
|
|
|
var offline_renderer = audio_ctx.startRendering();
|
|
if (offline_renderer)
|
|
offline_renderer.then(offline_callback).catch(function (err) {
|
|
console.log('Rendering failed: ' + err);
|
|
});
|
|
else
|
|
audio_ctx.oncomplete = function (e) {
|
|
offline_callback(e.renderedBuffer);
|
|
};
|
|
});
|
|
|
|
app.listenFor('RequestActionFX_PREVIEW_RATE', function (val) {
|
|
if (!q.is_ready) return;
|
|
if (AudioUtils.previewing) {
|
|
AudioUtils.FXPreviewStop();
|
|
app.fireEvent('DidStopPreview');
|
|
return;
|
|
}
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
var duration = (region.end - region.start) / val;
|
|
|
|
var originalBuffer = wavesurfer.backend.buffer;
|
|
var new_offset = ((start / 1) * originalBuffer.sampleRate) >> 0;
|
|
var new_len = ((duration / 1) * originalBuffer.sampleRate) >> 0;
|
|
var old_len = ((end / 1) * originalBuffer.sampleRate) >> 0;
|
|
|
|
// -----
|
|
var stretch_ratio = new_len / old_len;
|
|
|
|
AudioUtils.FXPreview(start, end, AudioUtils.FXBank.Rate(stretch_ratio));
|
|
|
|
app.fireEvent('DidStartPreview');
|
|
});
|
|
|
|
app.listenFor('RequestActionFX_SPEED', function (val) {
|
|
if (!q.is_ready) return;
|
|
|
|
app.fireEvent('RequestPause');
|
|
|
|
var region = wavesurfer.regions.list[0];
|
|
var dims = [0, 0];
|
|
|
|
function handleStateInline(start, end) {
|
|
app.fireEvent('StateRequestPush', {
|
|
desc: 'Apply Speed (fx)',
|
|
meta: [start, end],
|
|
data: wavesurfer.backend.buffer
|
|
});
|
|
}
|
|
|
|
if (!region) {
|
|
wavesurfer.regions.add({
|
|
start: 0.00,
|
|
end: wavesurfer.getDuration() - 0.00,
|
|
id: 't'
|
|
});
|
|
region = wavesurfer.regions.list[0];
|
|
}
|
|
|
|
|
|
var start = q.TrimTo(region.start, 3);
|
|
var end = q.TrimTo((region.end - region.start), 3);
|
|
var duration = (region.end - region.start) / val;
|
|
duration = q.TrimTo(duration, 3);
|
|
|
|
handleStateInline(start, end);
|
|
|
|
var fx_buffer = AudioUtils.Copy(start, end);
|
|
var originalBuffer = wavesurfer.backend.buffer;
|
|
var new_offset = ((start / 1) * originalBuffer.sampleRate) >> 0;
|
|
var new_len = ((duration / 1) * originalBuffer.sampleRate) >> 0;
|
|
var old_len = ((end / 1) * originalBuffer.sampleRate) >> 0;
|
|
|
|
/*
|
|
var emptySegment = wavesurfer.backend.ac.createBuffer (
|
|
wavesurfer.SelectedChannelsLen,
|
|
new_len,
|
|
originalBuffer.sampleRate
|
|
);*/
|
|
|
|
q.in_fx = true;
|
|
app.ui.InteractionHandler.on = true;
|
|
var fx = AudioUtils.FXBank.Speed(val);
|
|
|
|
var getOfflineAudioContext = function (channels, sampleRate, duration) {
|
|
return new (window.OfflineAudioContext ||
|
|
window.webkitOfflineAudioContext)(channels, duration, sampleRate);
|
|
};
|
|
var audio_ctx = getOfflineAudioContext(
|
|
wavesurfer.SelectedChannelsLen, // orig_buffer.numberOfChannels,
|
|
originalBuffer.sampleRate,
|
|
new_len
|
|
);
|
|
|
|
var source = audio_ctx.createBufferSource();
|
|
source.buffer = fx_buffer;
|
|
|
|
var filter = fx.filter(audio_ctx, audio_ctx.destination, source, duration);
|
|
|
|
source.start();
|
|
|
|
var offline_callback = function (rendered_buffer) {
|
|
|
|
AudioUtils.Replace(start, end, rendered_buffer);
|
|
|
|
wavesurfer.regions.clear();
|
|
wavesurfer.regions.add({
|
|
start: start,
|
|
end: start + duration,
|
|
id: 't'
|
|
});
|
|
|
|
app.fireEvent('RequestSeekTo', (start / wavesurfer.getDuration()));
|
|
|
|
OneUp('Applied Speed (fx)');
|
|
|
|
if (filter.length > 0) {
|
|
for (var i = 0; i < filter.length; ++i) filter[i].disconnect();
|
|
} else filter && filter.disconnect && filter.disconnect();
|
|
|
|
// is this needed?
|
|
rendered_buffer = fx_buffer = filter = null;
|
|
source.disconnect();
|
|
// audio_ctx.close ();
|
|
// -
|
|
q.in_fx = false;
|
|
app.ui.InteractionHandler.on = false;
|
|
};
|
|
|
|
var offline_renderer = audio_ctx.startRendering();
|
|
if (offline_renderer)
|
|
offline_renderer.then(offline_callback).catch(function (err) {
|
|
console.log('Rendering failed: ' + err);
|
|
});
|
|
else
|
|
audio_ctx.oncomplete = function (e) {
|
|
offline_callback(e.renderedBuffer);
|
|
};
|
|
});
|
|
|
|
app.listenFor('StateDidPop', function (state, undo) {
|
|
if (!q.is_ready) return;
|
|
app.fireEvent('RequestPause');
|
|
|
|
wavesurfer.regions.clear();
|
|
wavesurfer.loadDecodedBuffer(state.data);
|
|
|
|
if (state.cb) state.cb();
|
|
|
|
var new_durr = wavesurfer.getDuration();
|
|
app.fireEvent('DidUpdateLen', new_durr);
|
|
|
|
if (state.meta && state.meta.length > 0) {
|
|
if (state.meta[1]) {
|
|
wavesurfer.regions.add({
|
|
start: state.meta[0] / 1,
|
|
end: state.meta[0] / 1 + state.meta[1] / 1,
|
|
id: 't'
|
|
});
|
|
}
|
|
else {
|
|
if (!new_durr) new_durr = 0.0001;
|
|
app.fireEvent('RequestSeekTo', (state.meta[0] / new_durr));
|
|
}
|
|
}
|
|
|
|
if (undo) OneUp('Undo ' + state.desc);
|
|
else OneUp('Redo ' + state.desc);
|
|
});
|
|
|
|
|
|
// ---
|
|
app.listenFor('RequestChanToggle', function (chan_index, force_val) {
|
|
if (!q.is_ready) return (false);
|
|
|
|
if (wavesurfer.ActiveChannels.length <= chan_index) return (false);
|
|
|
|
var oldval = wavesurfer.ActiveChannels[chan_index];
|
|
var val = -1;
|
|
|
|
if (force_val) val = force_val;
|
|
else {
|
|
if (oldval === 1) val = 0;
|
|
else val = 1;
|
|
}
|
|
|
|
if (oldval !== val) {
|
|
wavesurfer.ActiveChannels[chan_index] = val;
|
|
if (val === 0) {
|
|
--wavesurfer.SelectedChannelsLen;
|
|
// silece the channel itself
|
|
|
|
if (chan_index === 0) {
|
|
wavesurfer.backend.gainNode2.gain.value = 0.0;
|
|
} else {
|
|
wavesurfer.backend.gainNode1.gain.value = 0.0;
|
|
}
|
|
}
|
|
else {
|
|
++wavesurfer.SelectedChannelsLen;
|
|
|
|
if (chan_index === 0) {
|
|
wavesurfer.backend.gainNode2.gain.value = 1.0;
|
|
} else {
|
|
wavesurfer.backend.gainNode1.gain.value = 1.0;
|
|
}
|
|
}
|
|
|
|
wavesurfer.ForceDraw();
|
|
app.fireEvent('DidChanToggle', chan_index, val);
|
|
}
|
|
});
|
|
|
|
// ----
|
|
wavesurfer.on('region-updated', function () {
|
|
if (wavesurfer.regions.list[0]) {
|
|
app.fireEvent('DidCreateRegion', wavesurfer.regions.list[0]);
|
|
}
|
|
});
|
|
wavesurfer.on('region-update-end', function () {
|
|
app.fireEvent('DidCreateRegion', wavesurfer.regions.list[0]);
|
|
|
|
var start = wavesurfer.regions.list[0].start;
|
|
if (!wavesurfer.isPlaying())
|
|
app.fireEvent('RequestSeekTo', (start / wavesurfer.getDuration()));
|
|
});
|
|
wavesurfer.on('cursorcenter', function (e) {
|
|
app.fireEvent('DidCursorCenter', e, wavesurfer.ZoomFactor);
|
|
});
|
|
|
|
var wave = wavesurfer.drawer.canvases[0].wave.parentNode;
|
|
|
|
var drag_x = 0;
|
|
var drag_move = function (e) {
|
|
|
|
var diff = drag_x - e.clientX;
|
|
|
|
// find diff percentage from full width...
|
|
|
|
// drag the waveform now
|
|
app.fireEvent('RequestPan', diff);
|
|
|
|
drag_x = e.clientX;
|
|
};
|
|
|
|
app.listenFor('RequestZoom', function (diff, mode) {
|
|
var wv = wavesurfer;
|
|
|
|
// compute new ZoomFactor...
|
|
diff *= wv.ZoomFactor;
|
|
|
|
// compute availabel left ZoomFactor
|
|
if (mode === -1) {
|
|
var width = wv.drawer.width;
|
|
var available_pixels = width - width / wv.ZoomFactor;
|
|
var target = wv.ZoomFactor - 1;
|
|
if (target <= 0) return;
|
|
|
|
var old_zoomfactor = wv.ZoomFactor;
|
|
wv.ZoomFactor += (diff * target) / available_pixels;
|
|
if (wv.ZoomFactor < 1) wv.ZoomFactor = 1;
|
|
|
|
var new_vis_dur = wv.getDuration() / wv.ZoomFactor;
|
|
|
|
if (new_vis_dur <= 0.5) {
|
|
wv.ZoomFactor = old_zoomfactor;
|
|
return;
|
|
}
|
|
|
|
wv.VisibleDuration = new_vis_dur;
|
|
|
|
var time_moved = wv.VisibleDuration * (diff / wv.drawer.width);
|
|
wv.LeftProgress += time_moved;
|
|
|
|
if (wv.LeftProgress + wv.VisibleDuration >= wv.getDuration()) {
|
|
wv.LeftProgress = wv.getDuration() - wv.VisibleDuration;
|
|
}
|
|
else if (wv.LeftProgress < 0) {
|
|
wv.LeftProgress = 0;
|
|
}
|
|
}
|
|
else if (mode === 1) {
|
|
var width = wv.drawer.width;
|
|
var available_pixels = width - width / wv.ZoomFactor;
|
|
var target = wv.ZoomFactor - 1;
|
|
if (target <= 0) return;
|
|
|
|
var old_factor = wv.ZoomFactor;
|
|
wv.ZoomFactor -= (diff * target) / available_pixels;
|
|
if (wv.ZoomFactor < 1) wv.ZoomFactor = 1;
|
|
var temp = wv.getDuration() / wv.ZoomFactor;
|
|
if (temp + wv.LeftProgress > wv.getDuration()) {
|
|
wv.ZoomFactor = old_factor;
|
|
}
|
|
else {
|
|
if (temp <= 0.5) {
|
|
wv.ZoomFactor = old_factor;
|
|
return;
|
|
}
|
|
|
|
wv.VisibleDuration = temp;
|
|
}
|
|
// -
|
|
}
|
|
|
|
// wv.ZoomFactor -= Math.abs (diff / (wv.drawer.width / 2));
|
|
// console.log( diff + " BLAH " + wv.ZoomFactor + ' ' + (diff / wv.drawer.width) );
|
|
wv.ForceDraw();
|
|
app.fireEvent('DidZoom', [wavesurfer.ZoomFactor, (wavesurfer.LeftProgress / wavesurfer.getDuration()) * 100, wavesurfer.params.verticalZoom]);
|
|
});
|
|
|
|
app.listenFor('RequestPan', function (diff, mode) {
|
|
var wv = wavesurfer;
|
|
|
|
if (mode === 1) diff *= wv.ZoomFactor;
|
|
else if (mode === 2) {
|
|
var time_moved = wv.getDuration() * (diff / wv.drawer.width);
|
|
wv.LeftProgress = time_moved;
|
|
|
|
wv.ForceDraw();
|
|
app.fireEvent('DidZoom', [wavesurfer.ZoomFactor, (wavesurfer.LeftProgress / wavesurfer.getDuration()) * 100, wavesurfer.params.verticalZoom]);
|
|
|
|
return;
|
|
}
|
|
|
|
if (wv.ZoomFactor > 0) {
|
|
// drag and draw by X pixels...
|
|
var time_moved = wv.VisibleDuration * (diff / wv.drawer.width);
|
|
wv.LeftProgress += time_moved;
|
|
|
|
if (wv.LeftProgress + wv.VisibleDuration >= wv.getDuration()) {
|
|
wv.LeftProgress = wv.getDuration() - wv.VisibleDuration;
|
|
}
|
|
else if (wv.LeftProgress < 0) {
|
|
wv.LeftProgress = 0;
|
|
}
|
|
|
|
wv.ForceDraw();
|
|
app.fireEvent('DidZoom', [wavesurfer.ZoomFactor, (wavesurfer.LeftProgress / wavesurfer.getDuration()) * 100, wavesurfer.params.verticalZoom]);
|
|
}
|
|
});
|
|
|
|
|
|
wave.addEventListener('mousedown', function (e) {
|
|
if (e.which === 3) {
|
|
e.preventDefault();
|
|
|
|
wavesurfer.Interacting |= (1 << 1);
|
|
|
|
drag_x = e.clientX;
|
|
wave.className = 'pk_grabbing';
|
|
|
|
document.addEventListener('mousemove', drag_move, false);
|
|
return (false);
|
|
} else {
|
|
app.fireEvent('MouseDown');
|
|
app.fireEvent('RequestChanToggle', 0, 1);
|
|
app.fireEvent('RequestChanToggle', 1, 1);
|
|
}
|
|
}, false);
|
|
wave.addEventListener('mouseleave', function (e) {
|
|
document.removeEventListener('mousemove', drag_move);
|
|
|
|
if (wave.className !== '') {
|
|
wave.className = '';
|
|
setTimeout(function () {
|
|
wavesurfer.Interacting &= ~(1 << 1);
|
|
}, 20);
|
|
|
|
}
|
|
}, false);
|
|
wave.addEventListener('mouseup', function (e) {
|
|
if (e.which === 3) {
|
|
if (wave.className !== '') {
|
|
wave.className = '';
|
|
setTimeout(function () {
|
|
wavesurfer.Interacting &= ~(1 << 1);
|
|
}, 20);
|
|
}
|
|
document.removeEventListener('mousemove', drag_move);
|
|
}
|
|
}, false);
|
|
|
|
app.fireEvent('RequestResize');
|
|
|
|
app.listenFor('RequestViewFollowCursorToggle', function () {
|
|
var val = !wavesurfer.FollowCursor;
|
|
wavesurfer.FollowCursor = val;
|
|
|
|
// jump to curr cursor position
|
|
if (val && q.is_ready) {
|
|
wavesurfer.CursorCenter();
|
|
}
|
|
|
|
app.fireEvent('DidViewFollowCursorToggle', val);
|
|
});
|
|
app.listenFor('RequestViewPeakSeparatorToggle', function () {
|
|
if (!q.is_ready) return;
|
|
|
|
var val = !wavesurfer.params.limits;
|
|
wavesurfer.params.limits = val;
|
|
|
|
wavesurfer.ForceDraw();
|
|
|
|
app.fireEvent('DidViewPeakSeparatorToggle', val);
|
|
});
|
|
|
|
|
|
app.listenFor('RequestViewTimelineToggle', function () {
|
|
if (!q.is_ready) return;
|
|
|
|
var val = !wavesurfer.params.timeline;
|
|
wavesurfer.params.timeline = val;
|
|
|
|
wavesurfer.ForceDraw();
|
|
|
|
app.fireEvent('DidViewTimelineToggle', val);
|
|
});
|
|
|
|
app.listenFor('RequestViewCenterToCursor', function () {
|
|
if (!q.is_ready) return;
|
|
wavesurfer.CursorCenter();
|
|
});
|
|
|
|
|
|
app.listenFor('RequestZoomUI', function (type, val) {
|
|
if (!q.is_ready) return;
|
|
|
|
if (type === 0) {
|
|
wavesurfer.ResetZoom();
|
|
return;
|
|
}
|
|
|
|
if (type === 'h') {
|
|
wavesurfer.SetZoom(0.5, val);
|
|
}
|
|
|
|
if (type === 'v') {
|
|
wavesurfer.SetZoomVertical(val);
|
|
}
|
|
});
|
|
// -
|
|
|
|
|
|
this.ID3 = function (arraybuffer) {
|
|
var tags = null;
|
|
// var ttt = window.performance.now();
|
|
|
|
var bytes = new Uint8Array(arraybuffer);
|
|
if (bytes.length < 64) {
|
|
app.fireEvent('RequestActionID3', 1, tags);
|
|
return tags;
|
|
}
|
|
|
|
if (bytes[0] === 73 && bytes[1] === 68 && bytes[2] === 51) {
|
|
tags = ID3v2.ReadTags(arraybuffer);
|
|
|
|
//console.log( window.performance.now() - ttt );
|
|
// console.log( tags );
|
|
}
|
|
else if (bytes[4] === 102 && bytes[5] === 116 && bytes[6] === 121 &&
|
|
bytes[7] === 112 && bytes[8] === 77 && bytes[9] === 52) {
|
|
|
|
tags = ID4.ReadTags(arraybuffer);
|
|
// console.log( window.performance.now() - ttt );
|
|
// console.log( tags );
|
|
}
|
|
bytes = null;
|
|
|
|
app.fireEvent('RequestActionID3', 1, tags);
|
|
|
|
return (tags);
|
|
};
|
|
// ---
|
|
};
|
|
|
|
PKAE._deps.engine = PKEng;
|
|
|
|
})(window, document, PKAudioEditor); |