About Channels

About Channels, or how Math is not really that hard

What are those "channels" anyway?

It's just a fancy name for program - kind of like washing machine has a program. Gecho has relatively large memory for code - 1MB, of which currrent firmware occupies

Some channels are passive, have no interaction - you can just listen to them. Other react to your input in various forms. Some are for testing and some for settings or programming your own content. The list is long and expanding.

How many of them can we have?

Since they are selected by those four buttons, and we want more than four channels, you can press a button more than once, forming a longer number. For example, 11, 12, 13, 21, 111, or even 121314. This allows you to take really any unused number and define your own functionality under that combination. Of course there is a limit on number of channels: you can press at most 20 of them in in the sequence. And if it is 20 of them, then first one must be 1, otherwise it can be 1,2,3 or 4.

Why?

Because internally, an uint64_t variable type is used to store channel number. That variable can have maximum value of 18446744073709551616 (which is 2 to the power of 64). If you tried to write number 28446744073709551616 there, it won't fit in.

Of course, we only have buttons 1 to 4, so we can't really have channels like 1844... What is the maximum number then? It's all possible ways you can press those four buttons, forming a sequence from 1 to 14444444444444444444. Ouch. How many is that?

Let's use some "divide and conquer" strategy.

Imagine we only had two buttons, and we want to find out how many combinations is there between 1 and 222. It is easy to enumerate them all: 1, 2, 11, 12, 21, 22, 111, 112, 121, 122, 211, 212, 221, 222. Note how there are two consiting of only one press of a button, then four consisting of two, and eight consisting of three.

What happens if number of buttons increases to 3? There will be 3 possible channels of single digit (1,2,3), 9 channels of 2 digits (11, 12, 13, 21, 22, 23, 31, 32, 33), and 27 channels of 3 digits (too many to write here but trust me). Can you see the pattern emerging?

In case of two buttons, number of possible channels was 2 + 4 + 8, in case of three buttons, it was 3 + 9 + 27... or, if written another way, 2 + 2*2 + 2*2*2, 3 + 3*3 + 3*3*3. Why? Because, for example if you have 3 buttons, and you want to press them for 3 times (a random one each time), you have 3 possibilities to choose first button, 3 possibilities to choose second, and three possibilities to choose third one.

With four buttons, it is now easy to see, that all possible channels between 1 and 444 are calculated like 4 + 4*4 + 4*4*4. Which is 84.

If we wanted channels from 1 to 4444 instead, we need to add 4*4*4*4 to previous formula, to also include all channels that consist of 4 button presses. So, number of button presses = number of "4"s in the multiplication.

Now, we are close to the final answer, we just need to expand this few times... about 16 more times, oh... And also, we don't want number of all channels between 1 and 44444444444444444444, right? It was about 14444444444444444444 we wanted to know (because of uint64_t limit).

Let's split this problem in two - forget about the initial "1" for now. We are left with up to 19 random button presses: from 1 to 4444444444444444444. We already know how to calculate this:
4 + 4*4 + 4*4*4 + 4*4*4*4 + 4*4*4*4*4 + ... + 4*4*4*...*4*4*4 (19 "4"s in the last multiplication). Is there any short-hand notation? Sure there is: a sequence of multiplications of the same number x is called a "power" - x to the power of y, written as x^y. Now we can write 4 + 4^2 + 4^3 + 4^4 + ... + 4^19.

It is easy enough to type that into a calculator or spreadsheet:

The total sum of all combinations here is 366503875924. That's a lot of possible channels, isn't it? And, some of those numbers may be familiar to you, because as powers of 4 they are also powers of 2, which we meet in computers or other electronics all the time.

So, what about that second half of the whole problem, an outstanding button "1" that could have been pressed at the very beginning? I leave it for you to finish - the prize for first correct answer is a free wooden box :)

How do I add a new channel?

Unless you don't want to invent one from scratch (any C/C++ code can be wrapped in a function and assigned to a channel), the easiest way is to look at an existing one, clone it and modify.

A channel definition (these are stored in function custom_program_init() which you find in file custom_program.cpp) may typically look like this:
if(prog == 1122) //drum machine samples test
{
play_buffer((uint16_t*)0x080A8000, 137246, 1); //1=mono
while(1);
}

Thanks to the above code, after pressing "1122" and SET button, Gecho will play all samples that are stored at certain memory address, up to given length, and then halt using infinite loop.

if(prog == 3331) //cv_gate_test
{
custom_program_init(2); //recursive init channel #2
 
//disable some controls
PROG_enable_S1_control_noise_boost = false;
PROG_enable_S2_control_noise_attenuation = false;
 
//test-enable CV and Gate
TEST_enable_V1_control_voice = true;
TEST_enable_V2_control_drum = true;
 
PROG_drum_machine = true;
ACTIVE_FILTERS_PAIRS = FILTERS/2 - 2; //need to set aside some computation power
}

Here, for example, we want to extend default functionality of channel #2 so we recursively call it's init function first. Then, we override parameters which we want different in our new channel. Our goal is to change logic in which the first two ADC signals are parsed, effectively disabling IR proximity sensors and reacting to direct voltage on a given channel instead. Also, the number of active filters is slightly decreased (from 16 to 12 voices), because together with direct playback from FLASH memory it would be too much - DAC would not get served by MCU with new samples on time.

A channel may also need to have other files edited, for example when you want to do something completely new. Examples of this are there, and should be understandable from the comments scattered in the source code.