-
Notifications
You must be signed in to change notification settings - Fork 127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extend pattern language #375
base: master
Are you sure you want to change the base?
Conversation
I find it handy to have a shorthand notes based on the current key/scale, but that might change over the course of a pattern, and it's also good to be able to specify accidentals that override the current scale, so simply doing `(qnt @1)` in the the note function of the looper doesn't work as well as one might hope. So... I've tweaked rmap_helper to check if `(eval l)` returns a procedure and, if so to call that proc. Thinking about this, it should be possible just do `(if (procedure @1) (@1) @1)` in the player function. However, one thing that is definitely necessary to make this work is to change `(eval l)` to `(eval (interaction-environment))`, otherwise it tries to evaluate the wrong `f`
A common pattern in traditional tunes is the 𝅘𝅥𝅭 𝅘𝅥𝅮 rhythm, which proved to be annoyingly hard to express in the ':>' pattern language. You basically have to replace every note with 'note |', and then do 'dotted-crotchet | | quaver' which is somewhat annoying. So, I extended the language to make `note + note -` do the trick (it too me a while to spot that scheme was never going to let me do `note . note -`. I've also factored out the code that maps from a note symbol to a number and which works out where the actual notes are in a pattern and calculates their positions (both in time and within the pattern list). In theory, this should allow for the pattern interpretation part of the pattern player to be parameterised, but I've not really started on that work yet.
This lets us express the common 3 notes in the space of 2 triplet by doing something like: (60 62 63) |
Hey, thanks for the contribution - things are a bit hectic here rn but I'll look at it asap. |
No rush. Hope the jet lag isn’t hammering you too hard |
yep, soz - still on the todo list (and climbing) |
hey @pdcawley I've had a chance to have a look. cool! nice work getting it going, as you (now) know the guts of the pattern language stuff could do with some re-factoring. My thoughts on this PR at the moment are:
Overall, I think the best way forward is
I think that's a more principled way to go forward. So I think I won't merge this just yet. I don't suppose you'd be interested in helping out with some of the above work? Obviously it's open source, so I have no coercive power, but the more the merrier with implementation, and I'm happy to help out as well. Thoughts? |
One more thing, in terms of not breaking the existing stuff, not many folks are using this at present, so as long as the examples in |
That sounds like a way forward, certainly; I think it should be possible to do a lot of the symbol interpretation by having a per-interpreter environment that can be passed as the second argument to I have time on my hands with the lock down, so I think I'll start by trying to encapsulate an |
Hey @pdcawley that sounds like a solid approach. The other idea I'd had (a bit less clean than using different environments) was basically to have the pattern eval machinery macroexpand a big But I must confess I haven't thought about it deeply, so whichever approach seems best would be welcome. The main criteria is that the "original" language still works, and (ideally) that the internals of the pattern language stuff are a bit more modular and easier to reason about and modify. So I think you're well placed to help with that :) Re: the early/late eval, my preference is also for it to be late wherever possible, but in some cases it's going to have to be eager, and I think that's ok as well. |
The commit messages have most of what this is about. Basically it's to enabled dotted notes and shortened notes within the pattern language. For an example of what sort of thing it enables, try the following:
(:| pat-1 96 0 (play syn1 @1 (cosr (cosr 75 2 1/2) 1 1) (* 0.95 dur))
(g3 + a3 - b3 b3 c4 b3 a3 c4 b3 a3 g3 f#3 e3 | d3 |g3 + a3 - b3 b3 c4 b3 a3 c4 b3 g3 g3 f#3 g3 | g3 |
d4 (c4 b3) a3 (a3 b3) c4 (b3 a3) g3 b3 a3 g3 f#3 g3 a3 | a3 |
d4 (c4 b3) a3 (a3 b3) c4 (b3 a3) g3 b3 a3 g3 g3 f#3 g3 | g3 |
bb3 (a3 g3) bb3 (a3 g3) f#3 g3 a3 | d3 e3 f#3 g3 a3 bb3 a3 g3
bb3 (a3 g3) bb3 (a3 g3) f#3 g3 a3 | d3 e3 f#3 g3 g3 f#3 g3 |))`
with a 180 bpm tempo