^^ crow: druid scripts

Yes it is an input mode, I’ve made a git issue that it’s not documented. I implemented input.clock as a mirror of the norns handling of crow-clock-input. I wouldn’t want to change that behaviour in crow only, so perhaps it’s a discussion to have with some folks on the norns side.

I agree that it would be cool to have automatic sensing of the presence of a clock signal in the way you describe. It’s not trivial (as the above code suggests), but it would certainly be better to hide it from a userscript.

1 Like

Is there any way to try Sequins without purchasing a Crow, like in Max or something? Just not sure if the workflow is for me and would like to try before I buy.

sequins is a lua lib, you can use it in norns too :partying_face:

Also just realized that there’s no need to stop clocks, not really :tada:

1 Like

ya know you might have some luck sticking the code in jit.gl.lua and calling stuff with a metro object rather than clocks. there’s some timing issues with that lua object & it’s a few versions behind on the langauge but you might be able to get something going if you really wanna.

1 Like

Thanks @Oootini and @andrew. That’s encouraging. I have absolutely no coding experience though, so I’m going to have to brave a YT crash course or two before I begin to understand how this works.

One thing, though: when running it on a Norns/Max, does it spit out midi? Just wondering how it interfaces with voices and without a Crow.

Gotta start somewhere! splicer. midi should be straightforward I think.

Also step through the tutorial docs would be a good start.

2 Likes

Looking for a good way to sync a clock to an incoming pulse on input[1] … any ideas? Right now I’m using a tick that I increment and it works well for most things, but it would be handy to use other clock functions… I am taking a clock provided from my daw into gates from a midi->cv converter so I can control clock speed via the daw. I get 16th notes to input[1]

this is actually built into the input lib since v3 (though is undocumented as i was alerted to very recently):

-- uses 'change' mode detection
input[1].mode('clock')

-- or you can customize
input[1].mode('clock', 1.0, 0.2) -- 1V threshold with 0.2V hysteresis

we’ll make sure this is documented with the new release that’s forthcoming.

8 Likes

not quite a tutorial, but the crow scripting reference has a sequins section that covers a lot

1 Like

S2 of Maps is also a longer form method of absorbing sequins infos.

As someone with minimal coding background I have found it helpful to be typing out the scripts in Atom while watching to help absorb.

2 Likes

I’ve found the official Lua reference very helpful, and readable if you have some experience w/ coding. You can do a lot with normal tables.

Excerpted from the reference for Lua 5.3 (Lua 5.3 Reference Manual):

There are eight basic types in Lua: nil , boolean , number , string , function , userdata , thread , and table . […]

The type table implements associative arrays, that is, arrays that can have as indices not only numbers, but any Lua value except nil and NaN. […] Tables can be heterogeneous ; that is, they can contain values of all types (except nil ).

Tables are the sole data-structuring mechanism in Lua; they can be used to represent ordinary arrays, lists, symbol tables, sets, records, graphs, trees, etc. To represent records, Lua uses the field name as an index. The language supports this representation by providing a.name as syntactic sugar for a["name"]. […]

Like indices, the values of table fields can be of any type. In particular, because functions are first-class values, table fields can contain functions.

What does all this mean?

A table is a basic data type, like a number or a string. So anywhere you’d store a number or pass a string as an arg, you can reference a table instead.

A table implements an associative array. What’s an associative array? Imagine a teacher’s paper grade book with each student’s name written in pencil in a list, accompanied by their individual final grade. Finally, let’s say this teacher is compulsively thorough and will never write down a name w/o a grade beside it or vice versa.

The teacher can check a specific student’s grade, add a name and associated grade to the list, erase a name/grade, rearrange the order, change a specific grade, copy the list to another page, etc.

This could be seen as an associative array, that is: each name (“key”) is associated with a grade (“value”). But since the teacher is working with pencil and paper, nothing is stopping them from writing a number in place of a name. Or an obscene word in place of a grade. Or a letter grade in place of a name.

If they were perverse, extremely bored, and wrote really tiny, they could even fit another whole name/grade list into the space for one of the names. Or fit all that into the space for a single grade. And then erase it all.

Essentially, they could write anything that can be put to paper with pencil as either a key or the value associated with that key. In general, this is like a table in Lua.

So then, what kind of things can you with tables? All the kinds of things the teacher can do with the list of names/grades.

Within what constraints? The teacher is limited by what can be written on paper with a pencil. Lua limits us to using its basic data types for keys and values (excepting ‘nil’ and NaN). So you can use numbers, strings, true/false, other tables, and a few more things as either keys or values. Lua also gives us an enormous sheet of blank paper to start with, so we’re unlikely to run out of space on it.

Now that we have a firm grasp on 1) what a table is and 2) what we can do with it, how exactly can we work with tables in code?

To be continued…

<foreboding music wafts through gaps in the castle’s stone walls and a malevolant chuckle echoes off the vaulted ceilings, quickly yielding to a convulsive fit of coughing…>

4 Likes

Make sure to play with the window input mode as it’s designed precisely for this situation. Each time input[2] moves into a new voltage window, you’ll get an event input[2].window(win) ... end where win is an integer you can use to look up the table you mention (not sure you’d want a sequins in this instance).

3 Likes

Hi,

debut post here, so first of all thanks for being such a nice & inspiring group of people!!

:slight_smile:

I just got crow because i find it a fascinating concept and hope to make my own first babysteps in coding with it…

So far, i‘ve watched some of the maps videos and read through the documentation and several crow-related threads on here, but while i enjoyed most of it, much still went kind of over my head… so i was wondering if there is a book or other resource you could recommend to an absolute beginner in order to better understand some of the basics.

Basically, where would you start with no background in programming whatsoever…?

Any suggestions would be much appreciated!

2 Likes

welcome to lines!

the official scripting guide seems like a good place to start:

also, feel free to ask questions!

3 Likes

I’ve dipped into these lua tutorials quite a bit. They are not specific to crow, nor do they have a musical focus, but they are quite good if you have never programmed before

Enjoy! Crow is super fun

5 Likes

Find a task for crow that you can make a flowchart or verbal description of. This gives you a much better place to start. Instead of learning everything at once you only need to search through the references, guides and other peoples scripts to replace each step with a fragment of code.

9 Likes

I second this… Start with pencil and paper if you can, then revise your ideas until you can articulate them in plain language as a series of steps/conditions and the desired results. (Also known as a design doc in pseudocode.)

It may be helpful to keep in mind Crow has 2 inputs which can be configured to:

  • initiate a response to triggers/gates/clocks, peaks/threshold windows, and signals changing direction (increasing to decreasing and vice versa)
  • track CV
  • track inputted signal amplitude or freq (the latter only on Input 1)

And 4 outputs, which can be set to:

  • output continuous functions (lfo’s, envelopes)
  • output trigs/gates/clocks
  • output audio oscillator sounds
  • transform/reroute input CV

(…and probably some stuff I’m forgetting off the top of my head… feel free to chime in, gang. :slight_smile: )

Also, Crow can deal with signals from -5v to 10v.

So, given those building blocks, what might you create with them? How might you want to connect them to each other? What might happen to the signal once it’s inside Crow’s little bird brain?

In my experience, attempting to explain an idea to others provides a quick check of how thoroughly I understand it. Communicating my imagined design always highlights the weak spots that I need to refine.

Similarly, trying to teach what you think you actually do understand–no matter how trivial you consider it–makes plain where you need to firm up your understanding. As in most things, no one is above the fundamentals… learning them ever more deeply is an endless process.

Once you’ve got a good idea, implementation is usually straightforward, believe it or not. It’s just a matter of translating the plain language of each step into Lua. And Lua is simple, fun, and powerful, so you don’t need to know much about underlying computer systems to do a lot of damage with it.

Eventually you’ll gain the proficiency to manipulate signals inside Crow in all kinds of ways. And the technical stuff you learn will inspire more ideas, eventually becoming a pleasurable flow of coding/iterating/re-executing (facilitated by Lua’s efficiency and ability to be interactively scripted… this is where you’d use Druid for Crow).

Plus we can help you with the technical specifics here, on the boards!

8 Likes

As was to be expected, all super sound advice. Will check it out/ take it to heart, thanks a lot!

:pray:t2:

Also, while i did go through the scripting with druid guide already, i just now saw the links to further references at the bottom of the page :grimacing:

So i guess i‘m good for a while…

3 Likes

You could do it like this:

a = {}
a.cheese = {"brie"} — this is now a table within the table a, “brie” is at the first index of that table
a.fruit = {"pomegranate"} — as above
myvariable = “fruit” — needs to be a string

thefood = a[myvariable][1]

I’m sure there are plenty of other ways to do this of course!

Disclaimer: I’m not in front of the computer at the moment to test this, sorry!

1 Like

i think you’re looking for somethin like

a = {}
a.cheese01 = "brie"
a.fruit01 = "pomegranate"
myvariable = "fruit"
myindex = "01"

thekey = myvariable..myindex
thefood = a[thekey]

but yeah this is a bit confusing. the advice above suggests a different and maybe more “obvious” data structure:

a = {
  cheese = {"brie", "gouda"},
  fruit = {"pomegranate", "peach"}
}
  
function getfood(kind, index)
  return a[kind][index]
end
  
thefood = getfood('cheese', 1) 
print(thefood) -- 'brie'

in other words: use nested tables refelcting the data hierarchy you desire, rather than expressing that hierarchy in the text of the keys. (if you can.)


(wait, this question is 1month old? oh well. leaving it up anyways)

6 Likes