diff options
Diffstat (limited to 'site/app/twist/_unlive/twist_instance_WIP.js')
-rw-r--r-- | site/app/twist/_unlive/twist_instance_WIP.js | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/site/app/twist/_unlive/twist_instance_WIP.js b/site/app/twist/_unlive/twist_instance_WIP.js new file mode 100644 index 0000000..1c56cb6 --- /dev/null +++ b/site/app/twist/_unlive/twist_instance_WIP.js @@ -0,0 +1,350 @@ +var TwistInstance = function(index, twist) {
+ var self = this;
+ this.appdata = appdata;
+ this.waveform = null;
+ var waveformFile;
+ var waveformTab;
+ this.onPlays = [];
+ var sr = 44100;
+ var undoLevel;
+
+ function pushOperationLog(operation) {
+ var max = twist.storage.commitHistoryLevel;
+ if (!max) {
+ twist.storage.commitHistoryLevel = max = 16;
+ }
+ if (operationLog.length + 1 >= max) {
+ operationLog.shift();
+ }
+ operationLog.push(operation);
+ }
+
+ this.redraw = function() {
+ self.waveform.redraw();
+ };
+
+ this.close = function() {
+ self.waveform.destroy();
+ delete self.waveform;
+ };
+
+ this.show = function() {
+ self.waveform.show();
+ };
+
+ this.movePlayhead = function() {
+
+ };
+
+ function removeInstance(i) {
+ if (i < 0 || i > this.waveforms.length - 2) {
+ return;
+ }
+ self.waveform.destroy();
+ if (instanceIndex == i) {
+ instanceIndex = i + ((i == 0) ? 1 : -1);
+ self.waveform.show();
+ }
+ }
+
+
+ this.undo = function() {
+ if (playing) return;
+ self.waveform.cover(true);
+ operation("twst_undo", globalCallbackHandler, true, null, true);
+ };
+
+ this.cut = function() {
+ if (playing) return;
+ self.waveform.cover(true);
+ operation("twst_cut", globalCallbackHandler, true);
+ };
+
+ this.delete = function() {
+ if (playing) return;
+ self.waveform.cover(true);
+ operation("twst_delete", globalCallbackHandler, true);
+ };
+
+ this.copy = function() {
+ if (playing) return;
+ self.waveform.cover(true);
+ operation("twst_copy", null, true);
+ };
+
+ this.paste = function() {
+ if (playing) return;
+ self.waveform.cover(true);
+ operation("twst_paste", globalCallbackHandler, true);
+ // keep original play position / offset new
+ };
+
+ this.moveToStart = function() {
+ if (playing) return;
+ self.waveform.setSelection(0);
+ };
+
+ this.moveToEnd = function() {
+ if (playing) return;
+ self.waveform.setSelection(1);
+ };
+
+ this.selectAll = function() {
+ if (playing) return;
+ self.waveform.setSelection(0, 1);
+ };
+
+ this.selectNone = function() {
+ if (playing) return;
+ self.waveform.setSelection(0);
+ };
+
+ this.selectToEnd = function() {
+ if (playing) return;
+ self.waveform.alterSelection(null, 1);
+ }
+
+ this.selectFromStart = function() {
+ if (playing) return;
+ self.waveform.alterSelection(0, null);
+ }
+
+ this.play = function() {
+ if (playing) return;
+ auditioning = false;
+ recording = false;
+ operation("twst_play", playPositionHandler(), false, null, true);
+ };
+
+ this.stop = function() {
+ if (!playing) return;
+ self.waveform.cover(false);
+ app.insertScore("twst_stop");
+ };
+
+ function getAutomationData(start, end) {
+ var calls = [];
+ if (!self.currentTransform) return calls;
+ var automations = self.currentTransform.getAutomationData(start, end);
+ if (automations && automations.length > 0) {
+ for (let i in automations) {
+ if (automations[i].type == "modulation") {
+ calls.push(automations[i].data[0] + " \\\"" + automations[i].data[1] + "\\\"");
+ } else if (automations[i].type == "automation") {
+ calls.push("chnset linseg:k(" + automations[i].data + "), \\\"" + automations[i].channel + "\\\"");
+ }
+ }
+ }
+ return calls;
+ }
+
+ function handleAutomation(onready, calls) {
+ if (calls.length == 0) {
+ return onready(0);
+ }
+ var cbid = app.createCallback(function(ndata){
+ if (ndata.status == 1) {
+ onready(1);
+ } else {
+ self.errorHandler("Cannot parse automation data");
+ }
+ });
+
+ var call = [0, 1, cbid];
+ for (let c of calls) {
+ call.push(c);
+ }
+ app.insertScore("twst_automationprepare", call);
+ }
+
+ function compileVariScript(script, onComplete) {
+ var cbid = app.createCallback(function(ndata){
+ onComplete(ndata.status == 1);
+ // should maybe automatically refresh
+ });
+ }
+
+
+ function fftsizeCheck(selected, duration) {
+ if (self.currentTransform) {
+ for (var p in self.currentTransform.parameters) {
+ if (p.indexOf("fftsize") != -1) {
+ var val = self.currentTransform.parameters[p].getValue();
+ var minTime = (val / sr) * 2;
+ if ((selected[1] - selected[0]) * duration < minTime) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ this.record = async function() {
+ if (playing) return;
+ auditioning = false;
+ recording = true;
+ await app.enableAudioInput();
+ errorState = "Recording error";
+ self.waveform.cover(true);
+ var cbid = playPositionHandler();
+ var s = self.waveform.selected;
+ var items = [0, 1, cbid, s[0], s[1], s[2]];
+ app.insertScore("twst_record", items);
+ };
+
+ this.audition = function() {
+ if (playing) return;
+ if (!self.currentTransform) {
+ return self.play();
+ }
+ self.currentTransform.saveState();
+ var s = self.waveform.selected;
+ if (!fftsizeCheck(s, self.waveform.duration)) {
+ return self.errorHandler("Length too short for this transform");
+ }
+
+ auditioning = true;
+ recording = false;
+ errorState = "Playback error";
+ handleAutomation(function(automating){
+ var cbid = playPositionHandler();
+ var items = [
+ 0, 1, cbid, s[0], s[1], s[2],
+ self.currentTransform.instr, automating,
+ elCrossfades[0].val(), elCrossfades[1].val()
+ ];
+ app.insertScore("twst_audition", items);
+ }, getAutomationData(s[0], s[1]));
+
+ };
+
+
+ var scriptStack = [];
+ function applyScript(audition) {
+ if (playing) return;
+ var lastData;
+ var script = scriptStack.shift();
+ if (!script) {
+ setLoadingStatus(false);
+ if (lastData) {
+ console.log("ass", lastData);
+ globalCallbackHandler(lastData);
+ }
+ twist.setPlaying(false);
+ return;
+ }
+
+ if (audition) auditioning = true;
+ twist.setPlaying(true);
+ if (script.type == "operation") {
+ if (audition) {
+ return self.errorHandler("Only transform scripts can be auditioned");
+ }
+ self.waveform.cover(true);
+ onComplete = (script.instr == "twst_copy") ? null : globalCallbackHandler;
+ operation(script.instr, function(ndata){
+ lastData = ndata;
+ self.setPlaying(false);
+ applyScript(audition);
+ }, true, script.selection);
+ } else if (script.type == "transform") {
+ errorState = ((audition) ? "Audition" : "Transform" ) + " commit error";
+ if (!audition) {
+ setLoadingStatus(true, true);
+ }
+
+ for (let channel in script.channels) {
+ app.setControlChannel(channel, script.channels[channel]);
+ }
+ handleAutomation(function(automating){
+ if (audition) {
+ var cbid = playPositionHandler();
+ } else {
+ var cbid = app.createCallback(function(ndata) {
+ lastData = ndata;
+ self.setPlaying(false);
+ applyScript(audition);
+ });
+ }
+ var instr = "twst_" + ((audition) ? "audition" : "commit");
+
+ app.insertScore(instr, [
+ 0, -1, cbid, script.selection[0], script.selection[1], script.selection[2], script.instr, automating, script.crossfades[0], script.crossfades[1]
+ ]);
+ }, script.automation);
+ }
+ }
+
+ this.applyScript = async function(script, audition) {
+ if (playing) return;
+ scriptStack = [];
+ if (Array.isArray(script)) {
+ if (audition) {
+ return self.errorHandler("Only single scripts can be auditioned");
+ }
+ scriptStack = script;
+ } else {
+ scriptStack = [script];
+ }
+ if (self.storage.autosave && !audition) {
+ self.saveFile(null, function() {
+ applyScript(audition);
+ });
+ } else {
+ applyScript(audition);
+ }
+ };
+
+ async function innerCommit() {
+ if (playing) return;
+ if (!self.currentTransform) return;
+ var s = self.waveform.selected;
+ if (!fftsizeCheck(s, self.waveform.duration)) {
+ return self.errorHandler("Length too short for this transform");
+ }
+ watchdog.start("commit");
+ self.setPlaying(true);
+ setLoadingStatus(true, true);
+ var calls = getAutomationData(s[0], s[1]);
+
+ self.currentTransform.saveState();
+ var state = await self.currentTransform.getState();
+ state.type = "transform";
+ state.automation = calls;
+ state.crossfades = [elCrossfades[0].val(), elCrossfades[1].val()];
+ state.selection = [s[0], s[1], s[2]];
+ state.instanceIndex = instanceIndex;
+ pushOperationLog(state);
+
+ handleAutomation(function(automating){
+ var cbid = app.createCallback(function(ndata) {
+ watchdog.stop();
+ setLoadingStatus(false);
+ self.setPlaying(false);
+ if (ndata.status > 0) {
+ globalCallbackHandler(ndata);
+ } else {
+ var text;
+ if (ndata.status == -2) {
+ text = "Resulting file is too large";
+ }
+ self.errorHandler(text);
+ }
+ });
+ errorState = "Transform commit error";
+ app.insertScore("twst_commit", [0, -1, cbid, s[0], s[1], s[2], self.currentTransform.instr, automating, state.crossfades[0],state.crossfades[1]]);
+ }, calls);
+ }
+
+ this.commit = async function() {
+ if (self.storage.autosave) {
+ self.saveFile(null, function() {
+ innerCommit();
+ });
+ } else {
+ innerCommit();
+ }
+ };
+
+}; // end twist
\ No newline at end of file |