Tool Concept: Pmclip

PMClip - clip support within Renoise?
[left] [/left]

Well, a man from the future came to see me, and he had envisioned that clips could be achieved by means of scripting. (rhowaldt, sorry if you feel that I’ve quoted you outside the proper context, but there’s such a definite aura about the statement)

Of course it’s matter of opinion, but I agree with many of the members around here that “clips” should be allowed as part of a streamlined workflow when composing music. Having to look for a track, and copy-paste to a new location isn’t that hard, but it could be made obsolete by a proper clip implementation. Also, while having native clips in Renoise is cool, I believe that it would be even better to put it out in the open, and let the Renoise users shape the way it’s supposed to work.
The pre-planning of this tool started during the beta cycle, because I knew that such an idea would rock, but I had no idea how it would work, and therefore, no idea what features from the API would be needed. And it didn’t take long to realize that we had a show-stopper in front of us: before Renoise 2.6 RC2 was released, we had no way to detect changes to a pattern!

Ok, this is the moment where every Renoise in the world with a heart should thank Taktik, because he could see the problem too, and responded by introducing the all-powerful line notifiers as late as the Renoise 2.6 release candidate. Maybe it was his way of saying “yeah, let’s have clips and whatnot”…
So there we are. IMHO, I have brought a great idea to the table, but I am yet to disclose anything about the actual content of this idea.

Introduction

PMClip stands for “Poor Mans Clip”, and provides basic clip functionality within Renoise. It’s designed to be working transparently in the background, making sure that everything is up-to-date.

You can exchange clips between songs, build an expandable library of riffs…

Technically, the concept revolves around a simple idea: if we assign a unique color to a track, we can uniquely identify this track in the song. Extend this to multiple tracks, and we’ve got a way of “linking” several tracks together. Combined with some fancy pattern-matching methods, this should enable a clip-based workflow for most types of songs.

The user interface

Although the thing is designed to be working silently in the background, we need access to certain features. This is what the UI could contain:

Clip list

Topmost we have the list of clips, listing if it’s active or not), it’s color, name and whether it’s note, effects or both.

Create

Creates a new, empty clip in the list. Assign a name and custom color to it, define it’s length. Default colors are picked from a custom palette dialog

Delete

Delete the currently selected clip from the list and remove the custom color from matrix slots that are instances of this clip (but leave the pattern data intact)

Import

Import the currently active track as the new definition for the clip (notes and/or effect columns, and the length).
If the track has fewer note/effect columns than our existing definition, a prompt will appear asking if existing clip data should be preserved.

Match

Matches the track slots in the matrix that are identical to the current clip, and applies the clip’s custom color to those tracks.
Matching will take repeated data into consideration: if clip has a length of 8, and the pattern has a length of 64 but with 8 repeats of the clip, it is matched. Alternatively, a track with a length of 64, but only with matching data for the first 8 lines is not matched.
One could also specify a matching ratio, so tracks that are almost identical are brought up after matching has completed. An easy way to spot track variations.

Apply

Apply the current definition to all instances of the clip (definition of instances: the clips that have been marked with the same custom color as the current clip). If no instances are found, a dialog will ask if we want to output the clip to the current track instead, and hence, create the first instance.
When applying/writing contents to patterns, the clip can repeated throughout the length of the pattern (this is optional, see “repeat”). Thus, it’s possible to have clips with varying lengths in the same pattern.

Length

Decides the clip length. When a clip is written to a pattern that is longer than the clip, it is repeated.

Note/Effect columns

The checkboxes determine if note/effect columns are filtered out when matching/writing data. The number of columns can be specified using the numeric entry boxes.

Repeat

Enable this to automatically repeat clips across the duration of a pattern (if the clip is shorter than the pattern)

Clip editor

Not a full-featured pattern editor by any means, but rather a quick and dirty “text editor” with input validation

Palette

A custom palette dialog that list the possible clip colors. Careful not to use the standard Renoise colors, as each one should be unique!

As soon as LuaJIT finds its way into Renoise and realtime API functions are added, it’s a go from me.
But how stable is the current Beta of LuaJIT and what kind of procedures can be used in a safe way already?

Yeah, making the script performance really good is one of the interesting challenges of course. But how would a script like this benefit from realtime functions? AFAIK realtime functions are called at a much smaller intervals (audiorate), which could potentially slow down things instead of speeding them up.

For more CPU intensive tasks like matching tracks in a song, isn’t co-routines really the way to go?

I’m really curious to see this in action. Using colors in the matrix as indicator for repeated clip content, then simply copy and pasting them automatically is a really clever attempt to keep the Renoise pattern way of working, but also enable clip alike features. Brilliant, but I think we all need to see how and if this really does the job in practice.

I don’t think LuaJit will help us here in any way. Lua is out of the box extremely efficient for a dynamically typed language, which is one of the main reasons we decided to use it, and not a prettier language like for example python. Also the main problem in PMClip will be when and how you do something, copy pattern stuff for example. Aka, the main problem is the algorithm and not a few optimized CPU cycles from LuaJit here and there. Also if I understand all this correctly, then main job anyway will be done by Renoise internally -> copying pattern tracks, comparing pattern track content.

Creating the GUI and also the deciders (when to copy what to what) will be quite challenging. Let me know if you need any help of input from me!

looks exciting!
I have one problem though…

I don’t think I really know what clips are :unsure:

Is this more or less the same as ableton’s clips; it’s been so long since I used ableton that I can’t even remember what they really are!

just out of curiousity do you have a "working “beta” of this,or is it just ideas???

im liking the idea very much and im excited to see what the scripting-guru comes up with.

Clips are reusable content? Actually, it’s hard to define, which is also why I’m just putting it out here for open discussion.
I think this particular implementation is flexible enough to complement an existing workflow, instead of replacing it. Here’s an example:

You have a song that you’re pretty happy about, but there’s a few things about the drumbeat that just sucks. The problem is, that the beat is present throughout the entire song, so you’d have to look up each and every track…it’s not hard to do, but it’s still a lot of copy-paste/paste/paste/etc…

For that particular case, using PMClip would be a question of right-clicking the drum-track, and tagging it as a clip. Edit the stuff you want to change, and voila - the pattern data is replaced throughout your song (assuming that you have a 100% identical beat, which is perhaps not entirely realistic - this is why we should also have a matching ratio - much like a search engine - so we can spot the variations on the beat as well…)

Absolutely just ideas. I want to have an open discussion about where this thing could be taken.
Also, I don’t want to create another huge project that I’d would have to maintain - Duplex really is time-consuming enough as it is

I think it would be great if Pmclip gets pushed through for public use. Lately I’ve been centralizing any pattern data I make in whole note XRNS, 4, 5, 6, 7, 8, 9, etc. And in each XRNS I have a few centralized pattern data tracks, some pre-pattern tracks and a combined pattern track where I oversee all patterns used.

What about combining several tracks pattern data or splitting clip data to several tracks ? Should this be a manual move or use other tools like the split data to separate tracks tool ? I haven’t tried that tool yet though…

man, don’t worry about it. it was definite because i was pretty sure this needed to be implemented natively and it would not be possible through scripting. however, my being sure was born from a lack of knowledge about scripting in Renoise, and of course not being able to predict the things your mind conjures up.

actually, i was never that enthusiastic about the whole clip-idea, but seeing it proposed here, i kinda like it.

aaah! (=

i thought about this… just like functions in a programming language. one definition and it can be called n times from anywhere. also, i’d say it is the logical extension of the fact that blocks in the pattern matrix can be “linked”. i have a little question (maybe i’m slow and this is obvious by your description) but anyway here goes:

does one set the pattern slot to have the property “copy any changes to my content to these other slots” or will it be on a pattern basis?

edit: ok, i guess it’s on a “pattern level”

I guess it’s supposed to be on a slot basis (a slot being a square in the matrix). Otherwise, it wouldn’t be as flexible. You should be able to synchronize slots “sideways” as well as “vertically” (or in other words, paste the clip anywhere)

The point being, that no single slot is the “original clip”. They are ALL instances of the clip, and the clip definition change each time you enter a note inside a slot which has been tagged. The closest thing you would get to an “original clip” is that the definition is maintained in the PMClip dialog (the list of clips).

About clips,

what I would like to see - possibility to make clips from all components for provided range of pattern.

Which means…

For example we have pattern with 170BPM with 12TPB. Length of it is 96.

I would like to aggregate all pattern effects with automatizations in range 0 - 47 and propagate it like trough the track in way how Control P is working.

Now it is bit annoying - synchronisation automatizations with pattern effect / notes is a bit time cost…

Personally I think I would find this method of incorporating Clips too limiting and not enough of an advancement on the Matrix for me to use it, but nice to hear you are working on it. What is really needed within Renoise is a way to have separate clips for different section (Notes, Automation, Pattern Commands) the ability to have more than one Clip per block, so chord progression and drum fills can be created by layering Note clips, Automation possible to be separated or combined for multiple parameters, and the ability to have clips of different lengths, overlapping and starting at arbitrary points compared to the other clips.

But that is really a full Arranger redesign, as discussed a few times to one extent or another, and I do think there are probably many people who might find your tool useful so don’t let me put you off.

yes, makes sense ofc.

ok! working with slots sounds better since the patterns that you want to try out different versions of are in general meant to be played back at certain fixed times in the arrangement. also, it would be grand just to drag and drop different patterns in the slot to see what it sounds like.

resurrection because of my own idea, which, as kazakore correctly points out, seems quite similar. https://forum.renoise.com/t/idea-command-groups/33148

danoise, i’ve tried my hand at this and it is just too much for a newbie scripting exercise. how are you coming along on this one, if at all?

Danoise, I would save clips as instruments (Preappend “Clip:”) with a custom data format in a ‘sample’, as I prefer clips per song. This would include the clips pattern data (saved from block with keybinding, but marked block coordinates are not even available via LUA iirc) and pointers to all insertions of the clip for fast updating. Sorry to say there would be no way of showing where a clip is being used in the actual pattern editor, which makes it even worse.

Making a project like this requires enough ugly workarounds to be useful that you probably wanted to wait for better native arrangment instead?

Interesting idea, using samples as data containers. Have anyone done this already? If not, I guess lua’s serialize methods be useful here?

Not really - the initial idea is actually completely transparent, at least to my personal workflow. What’s ugly about it is that there’s little tolerance for matching elements that are not completely identical - I really want to see a more intelligent (‘search-engine-like’) way of matching content.
Problem with most ‘clip’ implementations is that you need to adapt to them, instead of the other way around.

Oh, ok. Well, with the sample as data container you could keep track of where the clip are being used which would be very fast. Clips could be both inserted and referenced, where alteration of any reference affects the others. There should also be an option to “unreference” a usage of a clip and make it revert to normal pattern data.

I prefer this approach to a custom made pattern editor, and it wouldn’t need a search engine. The main drawback is that there are no graphical indications in the pattern editor of where clips are being used, but that’s a problem with Renoise.

I don’t know about lua serialization but I encountered some library with “dump” in its name that could handle objects, tables et c. It would probably also need a header with pointers. Maybe there are more standardized ways of doing this with lua.

I’ve not stored data in the actual sample data, but I have stored data in a simple format for the ReSynth tool in the sample name.

Storing data within the sample may be interesting as read/write to/from Lua is a float value from -1 to +1. Might be best to lower the sample bitdepth to 8 bit, enumerate all 256 possible values and use a simple conversion table of 'byte value ↔ equivalent float value. Don’t want to save this data in a lossy format though!

Maybe an easier alternative would be to use the APIs renoise.Document class and store data as XML files. It could also be integrated into the native file browser somehow for importing?

this seems like a good idea, because then clips could be moved around between songs and distributed

but maybe a less advanced clip functionality could be scripted for a start, something like EPMClip, “Even Poorer Man’s Clip” :)

because there seems to me that maybe it’s possible to use the unknown renoise commands Cxxx and Exxx as clip markers (where the clip begins and where it ends) and then attach a number id to the clip

for example:

  
C-4 00 40 80 E001  
[more notes and fx data goes here]  
-- -- -- -- E001  
  

everything between the effect column tags E001 and E001 would define EPMClip number 1 (and everything between E303 and E303 would define the 303’th EPMClip’s contents, etc)

since we have a maximum of 8 different effect columns in renoise, there’s plenty of room for other (known) effect commands

then in the pattern editor we could place out another effect marker that is unknown to renoise (but would be known to the script of course):

  
-- -- -- -- C001   
  

this would place out the contents of EPMClip number 1 in the pattern editor whenever we called a keybinded function clips2pattern()

the script would naturally look for all instances of C001 in the current renoise song and then replace all matches with clip content data (which in this case is the data found between the first pair of E001 markers)

upon this replacement, the effect column clip marker C001 would be placed out by the script in order to keep the position tied to EPMClip 1

(because otherwise the poor man wouldn’t be able to assign new contents in EPMClips and have them automatically changed across the entire song)

if the poor man wanted to make EPMClips static (for example if he would like to assign that clip range to a new clip), he would simply delete the C001 marker manually in the pattern editor to exclude it from clips2pattern() iteration

and since the script would look for the first pair of Exxx in the tree, one could also manually delete the first Exxx and place it out beneth the second Exxx to make an alternative clip (assuming there is note data below the second Exxx marker), something like a clip stack

i don’t know enough lua yet so i can’t estimate how easy or difficult this would be to script, but maybe taktik’s find & replace script code could be adapted for the global find & replace procedures