Using cP

At the very least, I'd love to see cP make a comeback so that it's possible to send Pattern data from SuperDirt. The old implementation looked like this:

_cP :: (Enumerable a, Parseable a) => [Pattern a] -> String -> Pattern a
_cP ds s = innerJoin $ _cX f ds s
  where f a (VI v) = [Event a a (parseBP_E $ show v)]
        f a (VF v) = [Event a a (parseBP_E $ show v)]
        f a (VS v) = [Event a a (parseBP_E v)]
cP :: (Enumerable a, Parseable a) => Pattern a -> String -> Pattern a
cP d = _cP [d]
cP_ :: (Enumerable a, Parseable a) => String -> Pattern a
cP_ = _cP []

I've been looking at the new implementation of cF and trying to figure out how to port this to modern TidalCycles, but so far no dice.

Once upon a time I used a keyboard, along with the following code, to create arp Patterns and chords in TidalCycles based on the keys that were held down. Would be nice to be able to do that again- it seems my TidalCycle MIDI video is a bit out of date.

	(
		// here's the bit that sends MIDI data from all controllers to TidalCycles via OSC
		MIDIClient.init;
		MIDIIn.connectAll;
		~tidalSocket = NetAddr("127.0.0.1", 6010);
		e.notes=[];
		MIDIFunc.cc({|val, num, chan, src| ~tidalSocket.sendMsg('/ctrl', num, val/127.0);}, nil, nil, nil);
		MIDIFunc.noteOn({|veloc, num, chan, src| e.notes=e.notes.add(num); e.notes=e.notes.sort({|a,b| a>b}).reverse; ~tidalSocket.sendMsg('/ctrl', "notes", format("%", e.notes-60)); e.notes.postln;});
		MIDIFunc.noteOff({|veloc, num, chan, src| e.notes=e.notes.takeThese({|x| x==num}); ~tidalSocket.sendMsg('/ctrl', "notes", format("%", e.notes-60)); e.notes.postln;});
	);
1 Like

Hey @eris, I moved this to innards..

As far as I know cP is still there.. Is there a problem with it?

Actually...no! (I'm so embarrassed!) I don't know what I was doing, but for some reason I couldn't locate it and I thought it'd gone missing. Went to go look for it after seeing your reply, and it's there and just fine! Sorry about that >.>

Could probably just trash this topic honestly. I don't want to create confusion, especially since it seems the tutorial content I have posted on the matter should work just fine.

(thank you!)

Heh no worries!

Hi,

I could get the tutorial at http://ericfairbanks.org/2018/12/17/tidal-tutorial-part-4.html to run if I do
let chord = cP "notes"
instead of
let chord = cP "[]" "notes"

am I doing anything wrong ?

@eris
Am I right in understanding that "cP" is a pattern that's sent over OSC to a specific path that TidalCycles is listening to ?

If that's the case, are there any gotchas ? Like escaping quotes / etc. ?

I was playing with this a little bit - it looks like this lets you send over anything in mini-notation, but you're still limited to anything within that notation.

Does a function or translator exist that'll let you send over something like "slow 2 $ s 'bd*4'" over the pipe and then expand that string for evaluation ? If not, how could I go about building it ? What are the key functions I'd need to learn about to glue that together ? (obviously you could do something where you build the function and then put it into a buffer somewhere and then evaluate that, but that seems uncomfortable and clumsy - I'd rather build the pattern and then send that over to be evaluated.)

Hi @abertier64, yes that's right, the interface simplified a little bit since @eris wrote that tutorial. Part of the reason why some bits aren't well documented is that they're experimental and subject to change. If anything confusing/unexpected happens please post here and we can straighten things out.

@john_murphy Loosely speaking, currently Tidal can parse and evaluate the mini-notation, but not Haskell. However @lwlsn and I are looking at making an OSC api that might make this possible. What is it that you'd like to do?

Thanks @yaxu I was puzzled because the cF part worked right away but I could not get the cP part to work until I stumbled on the solution. I have yet to learn how to read Haskell signatures...

@yaxu There's a few things I would like to do with this - but let's take a few simple examples:

  1. We have a bank of 10 patterns.
  2. Each of these patterns is mapped to a button on apc mini controller and can be ON or OFF.
  3. When we put a button into an ON state, that pattern is added to a "cat" containing all the patterns currently in the ON state. When we put the button into an OFF state, it is removed from the "cat" containing all the patterns currently in the ON state.

or:

  1. I do some editing for a sequence by entering midi notes into a pseq in Supercollider, and I'm happy with the result. I save that value into a list, and I send the pattern over to Tidal with a slow / fast to indicate how many cycles it's going to take to run.

A lot of the state management is easier to do in Supercollider, so having bi-directional communication to take advantage of the strengths of each language would be very useful.

1 Like

I see, I think this work-in-progress might already do want you want:

It's very experimental at this stage, though.

I expected that there would be something with the "hint" package, but I didn't want to go too far down that path without knowing that it was the right way to proceed (and I got laughed out of the #haskell channel on irc for asking about this!)

This seems great - it's a small enough set of code that I can wrap my head around it and hopefully put in a PR or two as I work my way through it.

Seems like every time I ask a question, there's already a project started for it! :slight_smile:

2 Likes