Experimental Studio
24 04 2019

Luc Döbereiner, David Pirrò, Daniele Pozzi
During his residency, Luc is writing a piece for cello and double bass which will be premiered by Schallfeld at Villa Elizabeth, Berlin, on 29th May 2019. The piece is based on transitions between neighboring harmonics and multiphonics, which articulate both the affordances offered by the bodies of acoustic intstruments and the constraints of the musicians' own bodies (fingering techniques etc.), as well as the intersections of such limitations.
These transitions are formalized in the form of a constraint solver that, given a specific starting point (i.e. a given multiphonic on a specific position), finds all the possible solutions that satisfy the constraints in the chosen domain. It thus generates sequences of multiphonics / harmonics that can be played continuously  at each position, two different multiphonics / harmonics can be played at the same time, on neighboring strings.
So the constraint solver allows
 to get to know all the possibilities of the instrument
 to formalize transitions between all these possibilities
LD
I'm interested in having one thing played and one thing added on a neighboring string. So I have always a continuous sound that has usually two things played at the same time. And then you take off the first thing, you add another thing and so on. That kind of continuous transition. So, let's say, you are in a certain place, you are playing a certain mulptiphonic. Which other multiphonics or other harmonics could you play that have certain harmonic relationships  either they share notes, or they have certain intervals in their relation  that can be played  which you can play at the same time ?
I wrote some things by hand, you know, just actually imagining where's the hand, and then thinking of all the harmonics in there. And that took me like 2 hours to write 4 notes. And that may not even have been the most interesting possibility.
So I tried to think how could I do this search algorithm. For example, if you play an artificial harmonic, you have two fingers on one string, let's say your index and your ring finger. First of all, you can only go to neighboring strings, you cannot jump. Also because of the bow, you cannot bow two distant strings at the same time. Then you could go with your middle finger in between on the same area in the neighboring strings, but you can't go elsewhere. I like the crazy constraints of the body, somehow. It gives you something you could never come up with. And I also like it because the instrumentalists think of this all the time . Which fingering can I use, and so on. To have an algorithm, or a program, that can give them new things that they haven't thought about it's very nice, they discover the instrument in a new way.
LD
The basic idea of a constraint solver is that you have a domain.
A constraint solver is basically a search algorithm. You describe a problem not by describing an algorithm, or a recipe to solve it: you describe the output that you want. You describe the properties of something, and you have a domain that can be infinite or finite of things or values, whatever. The algorithm finds solutions that fit your constraints. Basically, it tries to find combinations in this domain.
DP
But solutions are, in general, not unique, right? If you have three variables, for example, and you establish a constraint relationship between them, it is not necessary that you have one possible outcome.
LD
No, there can be any number of solutions, depends also on the type of system you have. Normally most systems are able to find all solutions. The system that I have, it's a quite simple and basic system, that is able to spit out the solution and asks for a continuation function  it's actually a bit like this wreck thing. You can call, you get the next solution. So the solutions are ordered in a certain way, it depends on the order of the domain and the way you index the domain. Basically what it does is a backtracking search. Let's say your domain is all the values from 1 to 10. And the domain is the same for all the variables. Then it assigns a value from the domain to (it instantiates) the first variable. It checks whether this works, if it works it instantiates the next one. If that doesn't work, and if it doesn't work for all the possible values of the second variable, then it would go back to the first variable and assign it the next value from its domain.