Write 16 bools to a single index of a 16 bit table question!


#1

Hey

I am building a table based sequencer and I want to store the step values in a table.

I need 16 sequencers, so if I need to store 16 sequencer with 16 steps, you get 16X16= 256 index in a table needs to be used for it to work like this.

But I was thinking, that instead of storing each step of a sequence into it own index, where it take 16 indexes to store 16 steps, shouldn’t I be able to store the 16 bools for each step in one single index?

Like the same way that you can make 16 k-rate outputs of a single s-rate input:
outlet_k1 = inlet_s[o]
outlet_k2 = inlet_s[1]
outlet_k3 = inlet_s[3]
outlet_k4 = inlet_s[4]
Etc….

If I use a 16 bit table, I should be able to store the 16 bools in one index of a table, right?

I need to store some dial values in the same table, so probably going to use a 32 bit table for it, but I need all values to be stored in the same table. If I could limit the amount of index from 256 to just 16, by storing the 16 bools/steps in one single index, that would make it a lot simpler.

I have tried a few things the last couple of hours, but I can not get it working, I am not sure firstly how to get the input value stored to it’s own bit with a table/write and then secondly to play it back with a table/read.

Does anyone have an idea how to do this?

Did anyone already make such an object, that writes and reads bools from bits of an index in a table?

Here is some of what I have tried, where the 0 that is shifted << 1 is the step, in this case 0:
For writing:
attr_table.array[ inlet_a & (1 << 0) ]=_SSAT(inletv ,28)>>attr_table.GAIN;

For reading:
outlet_o= attr_table.array[_USAT( inleta & (1 << 0) ,attr_table.LENGTHPOW)]<<attr_table.GAIN;

That didn't work. It is probably too naive.....

I also tried:
For writing:
(attr_table.array[ inlet_a & (1 << 0) ]=_SSAT(inletv ,28)>>attr_table.GAIN) & (1 << 0);

For reading:
outlet_o= (attr_table.array[_USAT( inleta & (1 << 0) ,attr_table.LENGTHPOW)]<<attr_table.GAIN) & (1 << 0);

I tried more, but nothing worked and I don't remember all the things I tried, but that is 2 of the tests I made.

Here is the patch, for an easy start point and the 2 examples above:
Write to bits COMMUNITY 1.axp (19.9 KB)

Thanks in advance :slight_smile:


#2

C++ doesn't support directly accessing the bits in a value using the subscript operator [ ]. One could probably write a C++ class which implements a bit array, using an overloaded subscript operator, but this is not common.

Yes, you can store 16 boolean values in a 16 bit integer, but this is usually done using macros based on the normal bit operations: & | ~ >> << .

Google 'C++ bit access macros' and you will find plenty of info


#3

Cool, thanks, I will see what I can find.

I have managed to read the 16 booleans out of a bin16 and bin12, inividually. I am assuming each boolean is stored in a bit, since it can hold 16, but I might be wrong. In the patch above there is an example,, out to the right in the patch you can find it. I was just thinking I could apply a similar technic to a table, but maybe it is not that simple.

I think I have seen @rbrt has do something similar in an object, I just could not find it.

But then I also need to write to the bits first, to be able to read them.


#4

Here is a better example that show how to write and read booleans to bit, but with a bin16:

Write to bits 2 Only Bins 1 .axp (4.9 KB)

But yeah if this can't be done to arrays like that, I guess I have tinf another way.


#5

Okay, so this works for READING bit from a table. I used a bin16, where each value is a bit(I think) to add some values to a table and then I can read them back with this:
outlet_sc = attr_t.array[inlet_index] & (1 << inlet_bit);

inlet_bit is used to read every single toggle of the bin, stored in the table, on the same index.

I tried applying the exact same idea to writing but it doesn't seem to work:
(attr_table.array[ inlet_index ] & 1 << inlet_bit) =_SSAT(inletv ,28)>>attr_table.GAIN;

I get this error:
/Users/jakobskouborg/Documents/axoloti/build/xpatch.cpp:1102:73: error: lvalue required as left operand of assignment
(parent->instancenew2_i.array[ inlet_index ] & 1 << inlet_bit) =_SSAT(inletv ,28)>>parent->instancenew2_i.GAIN;
make: *** [/Users/jakobskouborg/Documents/axoloti/build/xpatch.bin] Error 1
shell task failed, exit value: 2

I feel like I am really close now. If anyone wants to chime in here is probably the best attempt by now. I am pretty sure that the read bits part of it works, now it's just last thing, to write:

Write to bits V2 4 Try something 4 For com 1 .axp (5.0 KB)

@tele_player
I looked here, and this is basically what I have been doing for the reading which works, but I am not getting the writing part right:
https://www.codementor.io/@hbendali/c-c-macro-bit-operations-ztrat0et6

Any suggestions are highly appreciated and I recommend checking the patch to see what the progress is. I think it's closeee.


#6

I don't think Axoloti is a very good way to learn C++, or programming in general. Good try!

So, if we want to SET a bit in attr_table.array[ inlet_index ] :
attr_table.array[inlet_index] |= 1 << inlet_bit;

Explained: take the value which is in attr_table.array[inlet_index] , and bitwise-OR it with (1 << inlet_bit)

If we want to CLEAR a bit in attr_table.array[inlet_index] :
attr_table.array[inlet_index] &= ~(1 << inlet_bit);

Explained: this is a little harder to understand. To torn OFF a bit, we use ~(1 << inlet_bit) to create a value that has all bits set EXCEPT the one we want to clear, then we bitwise-AND it with the destination.

This stuff is hard to explain in a forum - and seriously, a comprehensive study of C++ (and C) will make this much easier to understand. In Axoloti, there are multiple concepts all combined, which can be confusing.


#7

Thanks, I highly appreciate it. I got something working now, but it needs to be tweaked a bit.

I have taken some courses in c++, but I guess this is not beginner level.

Now I atleast knows the name of what I was doing and can do a bit of research and I have a starting point.

Atleast I got the reading part right, hehe :wink:

So thanks again :slight_smile:


#8

Far from being fluent in C, but I use these to do something similar to what i think you're doing:

int setbit(int var,int no, bool on){
if (on) var |= 1UL << no;
else var &= ~(1UL << no);
return var;
}

bool getbit(int var, int no){
return (var >> no) & 1U;
}

I put them in local data, and call them as i need them, e.g.

prev = setbit(prev,0,1);

to set the 0th bit of prev (an integer) to 1, or

if (getbit(prev,1))

to get 1 if the 1st bit of prev is set; etc.


#9

Ignoring variable names, that’s what I wrote. It is normal C/C++ bit-twiddling.


#10

Thanks I will check that out. The mechanism I made for now is a bit clumsy. This looks a lot simpler :slight_smile: