diff options
Diffstat (limited to 'site/app/twine/_hOLD/clip.js')
-rw-r--r-- | site/app/twine/_hOLD/clip.js | 499 |
1 files changed, 499 insertions, 0 deletions
diff --git a/site/app/twine/_hOLD/clip.js b/site/app/twine/_hOLD/clip.js new file mode 100644 index 0000000..1c4cc48 --- /dev/null +++ b/site/app/twine/_hOLD/clip.js @@ -0,0 +1,499 @@ +var Clip = function(twine, data, parent) {
+ var clip = this;
+ var loaded = false;
+ var waveformClip;
+ var waveformEdit;
+ var datatable;
+ this.channel = null;
+ var minWidth = 10;
+
+ if (!data) {
+ var id = twine.getNewID();
+ var data = {
+ name: "Clip " + id,
+ channel: -1,
+ id: id,
+ clipindex: null,
+ playLength: 1,
+ colour: "#" + (Math.random() * 0xFFFFFF << 0).toString(16),
+ position: 0,
+ // debugs:
+ duration: 1,
+ warp: false,
+ loop: false
+ };
+ } else {
+ loaded = true;
+ }
+ this.data = data;
+ Object.defineProperty(this, "colour", {
+ get: function() { return data.colour; },
+ set: function(x) {
+ data.colour = x;
+ clip.element.css("background-color", data.colour);
+ }
+ });
+
+ this.exportData = function() {
+ return data;
+ };
+
+ this.destroy = function(onComplete) {
+ var cbid = app.createCallback(function(ndata){
+ clip.element.remove();
+ clip.channel.removeClip(clip);
+ if (onComplete) {
+ onComplete(ndata);
+ }
+ });
+ app.insertScore("twine_removeclip", [0, 1, cbid, clip.data.clipindex]);
+ };
+
+ var dataMode = {
+ fnL: 0, fnR: 1, divisionsPerBeat: 2, duration: 3, beatsLength: 4, utilisedLength: 5,
+ warpMode: 6, pitch: 7, amp: 8, fftSize: 9, txtWinSize: 10, txtRandom: 11, txtOverlap: 12,
+ loop: 13, warp: 14, txtWinType: 15, // warp points are 16 + in table
+ position: -1, name: -2, channel: -3, clipindex: -4, playLength: -5
+ };
+
+
+ this.element = $("<div />").addClass("twine_clip").css({
+ "background-color": data.colour
+ }).click(function(e){
+ if (e.ctrlKey) {
+ twine.timeline.selectedClips.push(clip);
+ } else {
+ $(".twine_clip").css("outline", "none");
+ twine.timeline.selectedClips = [clip];
+ }
+console.log("ch", clip.data);
+ clip.element.css("outline", "1px dashed white");
+
+ var cui = twine.ui.clip;
+ cui.name.setValue(data.name);
+ cui.colour.setValue(data.colour);
+ cui.amp.setValue(data.amp);
+ cui.warp.setValue(data.warp);
+ cui.loop.setValue(data.loop);
+ cui.readType.setValue(data.warpMode);
+ cui.pitch.setValue(Math.round((Math.log(data.pitch) / Math.log(2)) * 12));
+ cui.fftSize.setValue(data.fftSize);
+ cui.winSize.setValue(data.txtWinSize);
+ cui.winRandom.setValue(data.txtRandom);
+ cui.winOverlap.setValue(data.txtOverlap);
+ cui.winType.setValue(data.txtWinType);
+
+ showEditWaveform($("#twine_clipdetailsright"));
+ twine.ui.showPane(twine.ui.pane.CLIP);
+ });
+ var elWaveClip = $("<div />").css({position: "absolute", width: "100%", height: "100%", top: "0px", left: "0px"}).appendTo(clip.element);
+ var elWaveText = $("<div />").css({position: "absolute", width: "100%", height: "100%", top: "0px", left: "0px", "font-size": "var(--fontSizeSmall)", color: "var(--fgColor1)"}).text(data.name).appendTo(clip.element);
+
+ var elResizeLeft = $("<div />").addClass("twine_clip_edge_left").appendTo(clip.element);
+ var elResizeRight = $("<div />").addClass("twine_clip_edge_right").appendTo(clip.element);
+ var elMove = $("<div />").addClass("twine_clip_centre").appendTo(clip.element);
+ var elWaveEdit = $("<div />").css({width: "100%", height: "100%", top: "0px", left: "0px"});
+
+ async function getDataFromTable(key) {
+ async function setFromKey(key) {
+ if (dataMode[key] < 0) return;
+ var value = await app.getCsound().tableGet(datatable, dataMode[key])
+ data[key] = value;
+ }
+
+ for (var k in dataMode) {
+ setFromKey(k);
+ }
+ }
+
+ function setClipAudioUnique(onComplete) {
+ var cbid = app.createCallback(async function(ndata){
+ await getDataFromTable();
+ if (onComplete) onComplete();
+ });
+ app.insertScore("twine_setclipaudiounique", [0, 1, cbid]);
+ }
+
+ function reloadAfterEdit(tables) {
+ twirl.loading.show("Loading");
+ var cbid = app.createCallback(async function(ndata){
+ datatable = ndata.datatable;
+ await getDataFromTable();
+ clip.redraw();
+ twine.setVisible(true);
+ twigs.setVisible(false);
+ twist.setVisible(false);
+ twirl.loading.hide();
+ });
+ var call = [0, 1, cbid, data.clipindex];
+ for (let t of tables) {
+ call.push(t);
+ }
+ app.insertScore("twine_clipreplacetables", call);
+ }
+
+ this.editInTwist = function(asUnique) {
+ if (!window.twist) return twirl.prompt.show("twist is unavailable in this session");
+ function edit() {
+ twist.boot(twine);
+ twist.bootAudio(twine);
+ var tables = [data.fnL];
+ if (data.fnR) tables.push(data.fnR);
+ twist.loadFileFromFtable(data.name, tables, function(ndata){
+ if (ndata.status > 0) {
+ twine.setVisible(false);
+ twist.setVisible(true);
+ }
+ }, reloadAfterEdit);
+ }
+ if (asUnique) {
+ setClipAudioUnique(edit);
+ } else {
+ edit();
+ }
+
+ };
+
+ this.editInTwigs = function(asUnique) {
+ if (!window.twigs) return twirl.prompt.show("twigs is unavailable in this session");
+ function edit() {
+ twigs.boot(twine);
+ var tables = [data.fnL];
+ if (data.fnR) tables.push(data.fnR);
+ twigs.loadFileFromFtable(data.name, tables, function(ndata){
+ if (ndata.status > 0) {
+ twine.setVisible(false);
+ twigs.setVisible(true);
+ }
+ }, reloadAfterEdit);
+ }
+ if (asUnique) {
+ setClipAudioUnique(edit);
+ } else {
+ edit();
+ }
+ };
+
+ this.setData = function(modeString, v, onComplete) {
+ data[modeString] = v;
+ if (dataMode[modeString] < 0) {
+ if (modeString == "name") {
+ elWaveText.text(data.name);
+ }
+ return;
+ }
+
+ function doSetData() {
+ if (!twirl.debug) app.getCsound().tableSet(datatable, dataMode[modeString], v);
+ }
+
+ doSetData();
+ if (onComplete) onComplete();
+ };
+
+ this.getPlaybackArgs = function(cbid, time) {
+ return [(time) ? time: 0, data.playLength, cbid, data.clipindex, data.playLength, clip.channel.getCsChannelName()];
+ };
+
+ this.play = function(onCallback) {
+ var cbid = app.createCallback(function(ndata) {
+ if (onCallback) onCallback(ndata);
+ }, true);
+ app.insertScore("ecp_playback_tst", clip.getPlaybackArgs(cbid));
+ }
+
+ async function getSourceTableData() {
+ var wavedata = [];
+ var tbL = await app.getTable(data.fnL);
+ wavedata.push(tbL);
+ if (data.hasOwnProperty("fnR") && data.fnR > 0) {
+ var tbR = await app.getTable(data.fnR);
+ wavedata.push(tbR);
+ }
+ return wavedata;
+ }
+
+ async function setClipWaveform(noRedraw) {
+ if (!waveformClip) {
+ waveformClip = new Waveform({
+ target: elWaveClip,
+ allowSelect: false,
+ showGrid: false,
+ bgColor: "rgb(255, 255, 255, 0)",
+ fgColor: "#000000"
+ });
+ setTimeout(async function(){
+ var sourceTables = await getSourceTableData();
+ waveformClip.setData(sourceTables, data.duration);
+ }, 100);
+ } else {
+ if (!noRedraw) waveformClip.redraw();
+ }
+ }
+
+ async function showEditWaveform(target) {
+ target.empty().append(elWaveEdit);
+ if (!waveformEdit) {
+ waveformEdit = new Waveform({
+ target: elWaveEdit,
+ allowSelect: true,
+ showGrid: true,
+ latencyCorrection: twirl.latencyCorrection // , markers:
+ });
+ setTimeout(async function(){
+ var sourceTables = await getSourceTableData();
+ waveformEdit.setData(sourceTables, data.duration);
+ }, 100);
+ } else {
+ waveformEdit.redraw();
+ }
+ }
+
+ this.setWarp = function(v) {
+ clip.setData("warp", v);
+ if (!data.warp && !data.loop && data.playLength > data.duration) {
+ data.playLength = data.duration;
+ clip.setSize();
+ }
+ };
+
+ this.setLoop = function(v) {
+ clip.setData("loop", v);
+ if (!data.warp && !data.loop && data.playLength > data.duration) {
+ data.playLength = data.duration;
+ clip.setSize();
+ }
+ };
+
+ this.setPitch = function(semitones) {
+ var pitchRatio = Math.pow(2, (semitones / 12));
+ clip.setData("pitch", pitchRatio);
+ if (data.warpMode == 0 && data.loop == 0 && data.warp == 0) {
+ data.playLength = data.duration / pitchRatio;
+ clip.setSize();
+ }
+ };
+
+ this.setWarpMode = function(v) {
+ var prevMode = data.warpMode;
+ clip.setData("warpMode", v);
+ if (prevMode == 0 && data.warpMode != 0 && !data.loop && !data.warp) {
+ data.playLength = data.duration;
+ clip.setSize();
+ }
+ };
+
+ this.setSize = function(noWaveRedraw) {
+ var width = data.playLength * twine.timeline.pixelsPerBeat;
+ clip.element.css("width", width + "px");
+ setClipWaveform(noWaveRedraw);
+ }
+
+ this.redraw = function(noWaveRedraw) {
+ if (!loaded) return;
+ var b = twine.timeline.beatRegion;
+ clip.setSize(noWaveRedraw);
+ if ((data.position + data.playLength) < b[0] || data.position > b[1]) {
+ return clip.element.hide();
+ }
+
+ var css = {
+ height: clip.channel.height + "px",
+ left: (data.position - b[0]) * twine.timeline.pixelsPerBeat + "px"
+ };
+ if (data.position < b[0]) {
+ css.left = "0px";
+ css.width = (data.playLength - (b[0] - data.position)) * twine.timeline.pixelsPerBeat + "px";
+ }
+
+ clip.element.show().css(css);
+ };
+
+ this.clone = function() {
+ var newData = Object.assign({}, data);
+ newData.id = twine.getNewID();
+ var c = new Clip(twine, newData, clip);
+ clip.channel.addClip(c);
+ app.insertScore("twine_cloneclip", [0, 1, app.createCallback(function(ndata) {
+ datatable = ndata.datatable;
+ c.loadFromDataTable(ndata.datatable, ndata.clipindex);
+ }), clip.data.clipindex]);
+ };
+
+
+ async function loadData(ndata, name, colour, defaultLength) {
+ twirl.loading.show("Loading");
+ if (ndata.status == -1) {
+ return twirl.errorHandler("File not valid");
+ } else if (ndata.status == -2) {
+ return twirl.errorHandler("File too large");
+ }
+ datatable = ndata.data.datatable;
+ await getDataFromTable();
+ data.clipindex = ndata.data.clipindex;
+ if (name) {
+ data.name = name;
+ }
+ if (defaultLength) {
+ data.playLength = data.duration;
+ }
+ elWaveText.text(data.name);
+ if (!colour) colour = twine.randomColour();
+ data.colour = colour;
+ loaded = true;
+ clip.redraw();
+ };
+
+ this.loadFromDataTable = async function(newDatatable, clipindex) {
+ datatable = newDatatable;
+ await getDataFromTable();
+ data.clipindex = clipindex;
+ loaded = true;
+ clip.redraw();
+ };
+
+ this.loadFromFtables = function(name, tables, colour) {
+ twirl.loading.show("Loading");
+ var cbid = app.createCallback(async function(ndata){
+ await loadData(ndata, name, colour);
+ twirl.loading.hide();
+ });
+ var call = [0, 1, cbid];
+ for (let t of tables) {
+ call.push(t);
+ }
+ app.insertScore("twine_loadftables", call);
+ };
+
+ this.loadFromPath = function(path, colour) {
+ twirl.loading.show("Loading");
+ var cbid = app.createCallback(async function(ndata){
+ await loadData(ndata, path, colour, true);
+ twirl.loading.hide();
+ });
+ app.insertScore("twine_loadpath", [0, 1, cbid, path]);
+ };
+
+ function getMaxClipWidth() {
+ var maxWidth = 9999;
+ if (!data.warp && !data.loop) {
+ maxWidth = data.duration * twine.timeline.pixelsPerBeat;
+ }
+ return maxWidth;
+ }
+
+ clip.movement = {
+ pos1: 0, pos2: 0, pos3: 0, pos4: 0, offset: 0, startX: 0, startY: 0, clipWidth: 0,
+ clipLeft: 0, clipTop: 0, lastLeft: 0, isCopying: false,
+ mouseDown: function(e, dragType) {
+ e.preventDefault();
+ twine.timeline.selectedClips.forEach(function(c){
+ c.movement.mouseDownInner(e, dragType);
+ });
+ },
+ mouseDownInner: function(e, dragType) {
+ e.preventDefault();
+ this.isCopying = false;
+ this.offset = clip.element.offset().left
+ this.clipWidth = parseFloat(clip.element.css("width"));
+ this.clipTop = parseFloat(clip.element.css("top"));
+ this.clipLeft = parseFloat(clip.element.css("left"));
+ this.startX = e.clientX - e.target.getBoundingClientRect().left;
+ this.startY = e.clientY - e.target.getBoundingClientRect().top;
+ this.pos3 = e.clientX;
+ this.pos4 = e.drag;
+ this.lastLeft = (this.pos3 - this.startX - clip.channel.offset.left);
+ $("html").on("mousemove", function(e){
+ clip.movement.doDrag(e, dragType);
+ }).on("mouseup", this.endDrag);
+ $("#container").css("cursor", "e-resize");
+ },
+ endDrag: function(e) {
+ e.preventDefault();
+ this.isCopying = false;
+ $("html").off("mouseup", this.endDrag).off("mousemove"); //, this.doDrag);
+ $("#container").css("cursor", "pointer");
+ },
+ doDrag: function(e, dragType) {
+ e.preventDefault();
+ twine.timeline.selectedClips.forEach(function(c){
+ c.movement.doDragInner(e, dragType);
+ });
+ },
+ doDragInner: function (e, dragType) {
+ e.preventDefault();
+ this.pos1 = this.pos3 - e.clientX;
+ this.pos2 = this.pos4 - e.clientY;
+ this.pos3 = e.clientX;
+ this.pos4 = e.clientY;
+
+ if (dragType == "right") {
+ var maxWidth = getMaxClipWidth();
+ var newWidth = (this.pos3 - this.startX - clip.channel.offset.left - this.clipLeft);
+ newWidth = twine.timeline.roundToGrid(newWidth);
+ if (newWidth > maxWidth) newWidth = maxWidth;
+ if (newWidth < minWidth) newWidth = minWidth;
+ data.playLength = newWidth / twine.timeline.pixelsPerBeat;
+ clip.element.css("width", newWidth + "px");
+
+ } else if (dragType == "left") {
+ var maxWidth = getMaxClipWidth();
+ var left = (this.pos3 - this.startX - clip.channel.offset.left);
+ left = twine.timeline.roundToGrid(left);
+ if (left < 0) left = 0;
+ var newWidth = (clipWidth - left) + this.clipLeft;
+ var cWidth, cLeft;
+ if (newWidth < minWidth) {
+ cWidth = minWidth, this.clipLeft + minWidth; //(minWidth - left) + clipLeft;
+ } else if (newWidth > maxWidth) {
+ cWidth = maxWidth, cLeft = this.lastLeft;
+ } else {
+ lastLeft = left;
+ cWidth = newWidth, cLeft = left;
+ }
+ clip.element.css({width: cWidth + "px", left: cLeft + "px"});
+
+ data.playLength = newWidth / twine.timeline.pixelsPerBeat;
+ data.position = Math.min(0, (left / twine.timeline.pixelsPerBeat) + twine.timeline.beatRegion[0]);
+
+ } else {
+ if (e.ctrlKey && !this.isCopying) {
+ this.isCopying = true;
+ clip.clone();
+ }
+
+ //var left = (this.pos3 - this.startX - clip.channel.offset.left);
+ var left = (this.pos3 - this.clipLeft - clip.channel.offset.left);
+ left = twine.timeline.roundToGrid(left);
+
+ //var top = (this.pos4 - this.startY - clip.channel.offset.top);
+ var top = (this.pos4 - this.clipTop - clip.channel.offset.top);
+ if (top > clip.channel.height) {
+ if (clip.channel.index + 1 < twine.timeline.channels.length) {
+ clip.channel.removeClip(clip);
+ twine.timeline.channels[clip.channel.index + 1].addClip(clip);
+ }
+ } else if (top < 0) {
+ if (clip.channel.index -1 >= 0) {
+ clip.channel.removeClip(clip);
+ twine.timeline.channels[clip.channel.index - 1].addClip(clip);
+ }
+ }
+ if (left < 0) left = 0;
+ //if (left > clip.channel.width - clipWidth) left = clip.channel.width - clipWidth;
+ if (left > clip.channel.width) left = clip.channel.width;
+ data.position = (left / twine.timeline.pixelsPerBeat) + twine.timeline.beatRegion[0];
+ clip.element.css("left", left + "px");
+ }
+ } // end doDragInner
+ };
+
+ elMove.mousedown(clip.movement.mouseDown);
+ elResizeRight.mousedown(function(e){
+ clip.movement.mouseDown(e, "right");
+ });
+ elResizeLeft.mousedown(function(e){
+ clip.movement.mouseDown(e, "left");
+ });
+
+};
\ No newline at end of file |