Single clock is what I arrived at too, thanks for confirming. I think I’m going to avoid GCF because I have a sneaking suspicion this will still be quite jittery and I’ll instead continually reconcile with the always-out-of-phase clock. I’m thinking of the old Air Force navigators’ motto my Dad told me: “Always off-course, always correcting” :slight_smile:

Good question, but I was just throwing simple pulses at the input, setting the pulses razor-thin in init() and then just invoking their outputs on the metro handler. I do a bit of math to figure out the new BPM but I wouldn’t think this would slow anything down:

function v_to_bpm(v)
    v = math.min(math.max(v, v_min), v_max)
    local ratio = (v - v_min) / (v_max - v_min)
    local new_bpm = bpm_min + (ratio * (bpm_max - bpm_min))
    local frac = new_bpm % 1
    new_bpm = new_bpm - frac
    return new_bpm + (frac < 0.5 and 0 or 1)
end

And then there’s calculating the new interval for the metro, even simpler:

function div_to_seconds(divisor)
    return 1 / (bpm / 60 * divisor)
end

The phase-reconciliation required a bit of rework but it actually feels cleaner. What I came up with is in here:

1 Like

My first script for Crow. A companion script for 0-ctrl. Outputs 1/2 are playing a melodic sequence with 50% chance of jumping to fifths. 3/4 are used for a slower moving bassline. Here to learn, input, ideas, challenges welcome!

function init()
  input[1].mode( 'scale', {0,3,5,7,10}, 12, 1.0 )
  input[2]{ mode = 'change', direction ='rising'}
end

count = 0

input[2].change = function()
  v = input[1].volts
  if math.random(100) > 50 then
    output[1].volts = ((v * 12) + 5) / 12
  else
    output[1].volts = v
  end
  output[2](pulse())
  count = count + 1
  if count >= 5 then
    count = 0
    output[3].volts = v
    output[4](pulse())
  end
end

Edit: not sure if this actually works is it should. I got wobbly off tune pitches when returning to the script. If someone wants to try and try it out, find what’s wrong I’d gladly get some input.

8 Likes

That’s cool. What do you patch from your 0-ctrl into crow generally?

1 Like

In this case pitch and the ‘clock’ gates. I will probably move this to Teletype when I get my hands on that.

1 Like

Looking pretty good already.
What i would do is change the random to 2 instead of 100. just a little bit shorter.
Place count in the init and make the “if count” a modulus calculations this way you don’t have to reset it all the time.

1 Like

Random 100 is for being able to choose freely on a percentage based possibility. I’ll definitely take on the modulus approach. Thanks.

Sorry,

Can someone please remind me what I’m doing wrong? Getting a syntax error when uploading scripts from druid?

Screen Shot 2020-10-29 at 7.54.40 AM

Be sure to launch druid from the same folder where the script files are. Or, in the current version of druid, you should get some filename autocompletion to help find where the script files are relative to druid’s working directory.

1 Like

I don’t get it. I set my bowery folder as the directory but the autocompletion in druid lists my home folder contents and not the bowery folder?

It should be relative to whichever directory druid was launched from. If your terminal is inside the Bowery folder when you run druid then that should be the working directory druid sees. So a typical session when you launch Terminal might go like this, using cd to change directories and assuming your Bowery folder is /path/to/my/bowery

$ cd /path/to/my/bowery
$ druid
r boids.lua

(The $ is not something you would type, I’m just using that to indicate the typical prompt when you’re in the Terminal shell itself, not yet inside druid)

1 Like

Thank you. I was forgetting the cd part when setting the path. All is working as it should.

1 Like

Hello! Think this is the right thread for this.
I’m working on my first original Crow script, and not being a coder I’m probably gonna need a little help!

I know the functions I want (described below), but I wanna bring in some patch-programmability, and have the outputs function a lil differently depending on what I/O I have going.

Summary

Sequential Shift & Hold / Random Source / CV+Gate

Config 1:
In 1: Clock
In 2: Voltage
Out 1-4: S&H / Stepped Random
USB: None
Every Clock pulse, step the S&H incoming voltage to the next plugged output, and the previous output(s) are set to a random selection of Unison, 4ths, 5ths, and 8va above/below the last voltage. Acts as a S&H when only out 1 is used

Config 2:
In 1: Clock
In 2: None
Out 1: Random Voltage (ignores clock)
Out 2: S&H
Out 3: Quantized Random
Out 4: Quantized S&H
USB: None

Config 3:
In 1: Clock
In 2: Voltage
Out 1: Random Voltage (ignores clock)
Out 2: S&H
Out 3: CV from Norns
Out 4: Gate from Norns
USB: Norns

I’m planning on firing up Druid this week and getting some of the basic functions down, since the Crow studies iirc help one set up clocks and random outputs, but if others have insights as to how I could make this script easy on myself, please lemme know!

2 Likes

Here’s an approach that takes a clock signal & selects a mode based off the voltage window. If you attenuate the clock signal, you’ll still get tempo information but also be able to select different behaviors (these are filler)

-- switch between behaviors based on high voltage of clock
-- in1: attenuated clock
-- out1: voltages from mode a
-- out2: voltages from mode b
-- out3: voltages from mode c
-- out4: voltages from mode d
-- TODO implement clocking 


function init()
    input[1].mode( 'window', {0,1,2,3,4,5}, 0.1 )
end

input[1].window = function(state)
    -- skip the low window (clock is down)
    if state ~= 1 then  
        -- switch behavior based off state
        if state == 2 then
            mode_a(state)
        end
        if state == 3 then
            mode_b(state)
        end
        if state == 4 then
            mode_c(state)
        end
        if state == 5 then
            mode_d(state)
       end 
    end
end

function mode_a(state)
    output[1].volts = state
    output[2].volts = 0
    output[3].volts = 0
    output[4].volts = 0
    
end

function mode_b(state)
    output[2].volts = state
    output[1].volts = 0
    output[3].volts = 0
    output[4].volts = 0
end

function mode_c(state)
    output[3].volts = state
    output[2].volts = 0
    output[1].volts = 0
    output[4].volts = 0
end

function mode_d(state)
    output[4].volts = state
    output[2].volts = 0
    output[3].volts = 0
    output[1].volts = 0
end
3 Likes

Single signal can encode up to four values — offset, frequency, amplitude and phase. In theory it is possible to extract all four of them. Since crow has only two inputs, these techniques can be helpful to pass more than two values around.

2 Likes

Here’s a trigger sequencer script I’ve been using to jam out rhythms quickly…

9 Likes

Heyyyyyyy! This is so dope. Love a tight little script that creates such a powerful tool!

4 Likes

Hi again! Trying to figure out exactly how the scales from the v2.0 update are used on outputs. I currently have this:

Summary

function init()
input[1]{mode = ‘change’
, direction = ‘rising’
}
v = input[2].volts
r = math.random() * 10.0 - 5.0
end

input[1].change = function()
output[2].volts = r
output[4].scale ({}, 12, 1.0) = r
end

Where I’m trying to define a couple things I’ll be using throughout right at the start of the script, and then apply the scale to one of them later on.

The section in the script ref reads:

Summary

output[n].scale( {scale}, temperament, scaling )
– scale: a table of note values, eg: {0,2,3,5,7,9,10}
– use the empty table {} for chromatic scale
– temperament: how many notes in a scale, default 12 (ie 12TET)
– scaling: volts per octave, default to 1.0, but use eg. 1.2 for buchla systems

– deactivate any active scaling with the ‘none’ argument
output[n].scale( ‘none’ )

Does this here mean than I’d first set the output (here being ‘r’), and then in another line set the scale? If the answer is yes: Apart from maybe mis-defining the output as being ‘r’, did I write out the syntax for the scale function correctly? I’m having trouble reading this section of the reference and want to make sure. Thank you!

Edit: Oop, accidentally figured it out while typing up the problem haha - The answer to my last question appears to have been yes, and druid seems to be running everything correctly now! I’ll still leave this post up.

(Please tell me if you’d like me to be posting less in this thread, by the way. I don’t want to clog up anyone’s notifications)

If I’m reading the ‘functions as arguments’ section of the ref correctly, I should be able to write a line that tells a random number to constantly update regardless of if the value is called anywhere. If this is the case, would anyone be able to give pointers on how to achieve that?
I’m my post earlier in the hour, if you look in the ‘init’ section: I defined a random value at script init, but didn’t realize until now that it’s therefore static until the next time the script starts up.

(Mod note: If your post is still the most recent post, it’s preferred to edit your existing post with more info. Totally fine to post here with help requests.)

Regarding the output scales, you have the setup call for output[4] correct, except for the = r at the end of that line. output[4].scale is a setup function, not a function that changes the value at the output jack.

The functions as arguments feature is specific to the ASL scripts. At the moment you don’t need that, as you are setting your outputs directly at each timestep.

I think what you need is to make a function that generates a new random value each time it’s called:

function r()
  return math.random() * 10.0 - 5.0
end

And then call that in your script:

input[1].change = function()
  output[2].volts = r() -- not the parenthesis to call the function
end

Then to clarify the output.scale syntax, you first need to setup the scale quantizer (best in the init script), then simply set output.volts in the input event. Like this:

function init()
  output[4].scale( {}, 12, 1.0 )
end

input[1].change = function()
  output[4].volts = r() -- call the random function again
end

Let me know if anything’s not clear!

5 Likes