Octophonic Chorus - Euclidian sequencers, sample buffers, FX chain sends

PRANDAM's icon

Hi!

I'm trying to translate an old Pure Data patch that I built to create a chorus of Text-To-Speech voices (each voice just saying syllables that were prerendered using a TTS system that could produce decent results in spanish at the time). The system used another script (made in Processing) that calculated the sun position (altitude and azimuth every few milliseconds). These numbers were then used to trigger each "singer". The singers (around 8 different voices) were built with an Euclidian sequencer and some effects, each one only playing files from a assigned folder. Then each voice audio would be sent to a circular panning subpatch where the audio signal would be assigned in a 360 degree space between 8 speakers. A partial example bellow (excuse the horror):

I'm trying to work the very first section with max and put together this simple sample player for some random syllables in a folder:


My questions are:

  1. Is possible to have a polybuffer for each voice? or could be better to do a preload of all samples (thousands of short wav files of 1 or 2 seconds) in just one polybuffer and then access by id? what could be a good method in this case? In the PD patch I opened each syllable from disk everytime it was needed with no buffering.

  2. what are the best practices for Euclidian sequencers? any recommended library?

  3. it's possible that each voice could do some kind of "send" to a FX chain before going to the Audio output? all voices (more than eight) could access this chain with different parameters? or would be just better to put separated FX subpatches/modules for each voice? (i did this on the PD patch but I don't think it's that elegant and felt redundant despite each voice had different values in each part of the chain)

  4. How can I put the logic of the Sun position calculation inside a Max patch? In the PD example I had to build a Processing script with all the logic and then send the azimuth and altitude values (among the syllable id and syllable text) using OSC. This is convoluted at best.

Excuse all the newbie questions and thanks for any help.


Roman Thilenius's icon

1.)
not sure if that helps, but polybuffer~ roughly corresponds to buffer~ inside a poly~, which is a bit more work but also offers more flexibility.
poly~ has a certain learning curve and is quite different from pd´s clone.

preloading media or not? should imho be a matter of a conscious decision what you want, not of programming style. audio is today mostly small enough to fit in RAM, on the other hand there are also contraindications about having poly~s or polybuffer~s with 1000 voices.

2.)
you´ll find a post somewhere here where someone suggests to use an algorithm lended from a (graphics) line antialiasing method, which outperforms any possible björklund algo implementation by some aspects.

but for up to 16 beats, precalculating and writing into a [coll] should be "best".

1, 0;
2, 1;
3, 0 0;
4, 1 0;
5, 1 1;
6, 0 0 0;
7, 1 0 0;
8, 1 0 1;
9, 1 1 1;
10, 0 0 0 0;
11, 1 0 0 0;
12, 1 0 1 0;
13, 1 0 1 1;
14, 1 1 1 1;
15, 0 0 0 0 0;
16, 1 0 0 0 0;
17, 1 0 0 1 0;
18, 1 0 1 0 1;
19, 1 0 1 1 1;
20, 1 1 1 1 1;
21, 0 0 0 0 0 0;
22, 1 0 0 0 0 0;
23, 1 0 0 1 0 0;
24, 1 0 1 0 1 0;
25, 1 0 1 1 0 1;
26, 1 0 1 1 1 1;
27, 1 1 1 1 1 1;
28, 0 0 0 0 0 0 0;
29, 1 0 0 0 0 0 0;
30, 1 0 0 0 1 0 0;
31, 1 0 0 1 0 1 0;
32, 1 0 1 0 1 0 1;
33, 1 0 1 1 0 1 1;
34, 1 0 1 1 1 1 1;
35, 1 1 1 1 1 1 1;
36, 0 0 0 0 0 0 0 0;
37, 1 0 0 0 0 0 0 0;
38, 1 0 0 0 1 0 0 0;
39, 1 0 0 1 0 0 1 0;
40, 1 0 1 0 1 0 1 0;
41, 1 0 1 0 1 1 0 1;
42, 1 0 1 1 1 0 1 1;
43, 1 0 1 1 1 1 1 1;
44, 1 1 1 1 1 1 1 1;
45, 0 0 0 0 0 0 0 0 0;
46, 1 0 0 0 0 0 0 0 0;
47, 1 0 0 0 0 1 0 0 0;
48, 1 0 0 1 0 0 1 0 0;
49, 1 0 0 1 0 1 0 1 0;
50, 1 0 1 0 1 0 1 0 1;
51, 1 0 1 1 0 1 1 0 1;
52, 1 0 1 1 1 0 1 1 1;
53, 1 0 1 1 1 1 1 1 1;
54, 1 1 1 1 1 1 1 1 1;
55, 0 0 0 0 0 0 0 0 0 0;
56, 1 0 0 0 0 0 0 0 0 0;
57, 1 0 0 0 0 1 0 0 0 0;
58, 1 0 0 0 1 0 0 1 0 0;
59, 1 0 0 1 0 1 0 0 1 0;
60, 1 0 1 0 1 0 1 0 1 0;
61, 1 0 1 0 1 1 0 1 0 1;
62, 1 0 1 1 0 1 1 0 1 1;
63, 1 0 1 1 1 1 0 1 1 1;
64, 1 0 1 1 1 1 1 1 1 1;
65, 1 1 1 1 1 1 1 1 1 1;
66, 0 0 0 0 0 0 0 0 0 0 0;
67, 1 0 0 0 0 0 0 0 0 0 0;
68, 1 0 0 0 0 0 1 0 0 0 0;
69, 1 0 0 0 1 0 0 0 1 0 0;
70, 1 0 0 1 0 0 1 0 0 1 0;
71, 1 0 0 1 0 1 0 1 0 1 0;
72, 1 0 1 0 1 0 1 0 1 0 1;
73, 1 0 1 0 1 1 0 1 1 0 1;
74, 1 0 1 1 0 1 1 1 0 1 1;
75, 1 0 1 1 1 1 0 1 1 1 1;
76, 1 0 1 1 1 1 1 1 1 1 1;
77, 1 1 1 1 1 1 1 1 1 1 1;
78, 0 0 0 0 0 0 0 0 0 0 0 0;
79, 1 0 0 0 0 0 0 0 0 0 0 0;
80, 1 0 0 0 0 0 1 0 0 0 0 0;
81, 1 0 0 0 1 0 0 0 1 0 0 0;
82, 1 0 0 1 0 0 1 0 0 1 0 0;
83, 1 0 0 1 0 1 0 0 1 0 1 0;
84, 1 0 1 0 1 0 1 0 1 0 1 0;
85, 1 0 1 0 1 0 1 1 0 1 0 1;
86, 1 0 1 1 0 1 1 0 1 1 0 1;
87, 1 0 1 1 1 0 1 1 1 0 1 1;
88, 1 0 1 1 1 1 0 1 1 1 1 1;
89, 1 0 1 1 1 1 1 1 1 1 1 1;
90, 1 1 1 1 1 1 1 1 1 1 1 1;
91, 0 0 0 0 0 0 0 0 0 0 0 0 0;
92, 1 0 0 0 0 0 0 0 0 0 0 0 0;
93, 1 0 0 0 0 0 0 1 0 0 0 0 0;
94, 1 0 0 0 0 1 0 0 0 1 0 0 0;
95, 1 0 0 0 1 0 0 1 0 0 1 0 0;
96, 1 0 0 1 0 0 1 0 1 0 0 1 0;
97, 1 0 0 1 0 1 0 1 0 1 0 1 0;
98, 1 0 1 0 1 0 1 0 1 0 1 0 1;
99, 1 0 1 0 1 1 0 1 0 1 1 0 1;
100, 1 0 1 1 0 1 1 0 1 1 0 1 1;
101, 1 0 1 1 1 0 1 1 1 0 1 1 1;
102, 1 0 1 1 1 1 1 0 1 1 1 1 1;
103, 1 0 1 1 1 1 1 1 1 1 1 1 1;
104, 1 1 1 1 1 1 1 1 1 1 1 1 1;
105, 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
106, 1 0 0 0 0 0 0 0 0 0 0 0 0 0;
107, 1 0 0 0 0 0 0 1 0 0 0 0 0 0;
108, 1 0 0 0 0 1 0 0 0 0 1 0 0 0;
109, 1 0 0 0 1 0 0 1 0 0 0 1 0 0;
110, 1 0 0 1 0 0 1 0 0 1 0 0 1 0;
111, 1 0 0 1 0 1 0 1 0 0 1 0 1 0;
112, 1 0 1 0 1 0 1 0 1 0 1 0 1 0;
113, 1 0 1 0 1 0 1 1 0 1 0 1 0 1;
114, 1 0 1 0 1 1 0 1 1 0 1 1 0 1;
115, 1 0 1 1 0 1 1 1 0 1 1 0 1 1;
116, 1 0 1 1 1 0 1 1 1 1 0 1 1 1;
117, 1 0 1 1 1 1 1 1 0 1 1 1 1 1;
118, 1 0 1 1 1 1 1 1 1 1 1 1 1 1;
119, 1 1 1 1 1 1 1 1 1 1 1 1 1 1;
120, 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
121, 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
122, 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0;
123, 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0;
124, 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0;
125, 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0;
126, 1 0 0 1 0 1 0 0 1 0 1 0 0 1 0;
127, 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0;
128, 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1;
129, 1 0 1 0 1 1 0 1 0 1 1 0 1 0 1;
130, 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1;
131, 1 0 1 1 0 1 1 1 0 1 1 1 0 1 1;
132, 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1;
133, 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1;
134, 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1;
135, 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1;
136, 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
137, 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
138, 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0;
139, 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0;
140, 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0;
141, 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0;
142, 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0;
143, 1 0 0 1 0 1 0 1 0 0 1 0 1 0 1 0;
144, 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0;
145, 1 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1;
146, 1 0 1 0 1 1 0 1 1 0 1 0 1 1 0 1;
147, 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1;
148, 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1;
149, 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1;
150, 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1;
151, 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1;
152, 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1;

PRANDAM's icon

Thanks for the suggestions, Roman, I'll try this out.