hi list
If you need a greater resolution for your values, just break them up into several bytes. This way, sending > a single 16 bit integer would take 4 bytes (address, bit 14-15, bit 13-7, bit 0-6).
That’s a great point. Everyone complains about MIDI now (not enough range, etc) but it’s **perfect* *for >what it was designed to do: send small event data quickly on much older, slower hardware. I little
bitmasking and away you go.
i second that! very neat point indeed. would it be to much to ask if anyone could clarify that bitmasking to a lower, non-programmers level? like sending 1234 with midi, how would you break it down bitwise?
thanks in advance
~/.jc
There are a few higher resolution values in the midi spec that you can use.. The bend value (one per channel, so 16 total assesses) is 14 bit and there are also nrpn messages which combine several control change messages to create a larger address and value space (14 bit). Or you can use sysex... I'm on a phone or I'd write some pseudo code for that...
On June 2, 2016 5:53:32 AM PDT, jamal crawford threen52@ml1.net wrote:
hi list
If you need a greater resolution for your values, just break them up into several bytes. This way, sending > a single 16 bit integer would take 4 bytes (address, bit 14-15, bit 13-7, bit 0-6).
That’s a great point. Everyone complains about MIDI now (not enough range, etc) but it’s **perfect* *for >what it was designed to do: send small event data quickly on much older, slower hardware. I little
bitmasking and away you go.
i second that! very neat point indeed. would it be to much to ask if anyone could clarify that bitmasking to a lower, non-programmers level? like sending 1234 with midi, how would you break it down bitwise?
thanks in advance
~/.jc
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> https://lists.puredata.info/listinfo/pd-list
Check this article as a starting point: https://en.wikipedia.org/wiki/Bit_manipulation
For breaking up and reassembling integers you only need bit shifting and bit masking. Bit masking is needed to get rid of unwanted bits. For example:
Mask some byte: 1 0 1 0 0 1 1 0 (your data) & 0 0 0 0 1 1 1 1 (your mask) = 0 0 0 0 0 1 1 0 (result)
How to make your mask:
(1 << 4) is 16 (00010000) (1 << 4)-1 is 15 (00001111) - here you go!
So the formular for making a mask where the rightmost N bits are all 1 is
(1 << N)-1
Now here's a simple example of how to break up a 16-bit integer into three 7-bit values:
unsigned char buf[3]; // buffer for three bytes int a = 1234; // your integer, in binary it's 0000 0100 1101 0010 const unsigned char m = (1 << 7)-1; // a 7-bit mask
a &= (1 << 16)-1; // clip beyond 16 bit, just to be sure
buf[0] = a & m; // get the 7 rightmost bit by masking, in this case 101 0010 (= 82) buf[1] = (a >> 7) & m; // shift 7 bits to the right and mask, in this case 000 1001 (= 9) buf[2] = (a >> 14) & m; // shift 2*7 bits to the right and mask, in this case 000 0000 (= 0)
or with a loop:
for (int i = 0; i < 3; ++i){ buf[i] = (a >> i*7) & m; }
Now the other way round:
unsigned char buf[3] = {82, 9, 0}; // integer 1234 broken up into three 7-bit values int a = 0; // integer to be reassembled
a += (int) buf[0]; // just 82 a += (int) buf[1] << 7; // 9 shifted 7 bits to the left is 1152 a += (int) buf[2] << 14; // 0 shifted 14 bits to the left is 0
/* a is now 82 + 1152 = 1234 */
or with a loop:
for (int i = 0; i < 3; ++i){ a += (int) buf[i] << i*7; // make sure to first cast the unsigned char (byte) to an integer before shifting it to the left!!! }
As you see, working with 7-bit data is actually quite neat. Just check if incoming bytes are bigger than 127 to distinguish between 'system messages' and actual data. This way it's quite simple to build your own little protocol.
Christof
Gesendet: Donnerstag, 02. Juni 2016 um 14:53 Uhr Von: "jamal crawford" threen52@ml1.net An: pd-list@lists.iem.at, danomatika@gmail.com Betreff: Re: [PD] Pduino sysex vs. OSC advice (Christof Ressi)
hi list
If you need a greater resolution for your values, just break them up into several bytes. This way, sending > a single 16 bit integer would take 4 bytes (address, bit 14-15, bit 13-7, bit 0-6).
That’s a great point. Everyone complains about MIDI now (not enough range, etc) but it’s *perfect* for >what it was designed to do: send small event data quickly on much older, slower hardware. I little >bitmasking and away you go.
i second that! very neat point indeed. would it be to much to ask if anyone could clarify that bitmasking to a lower, non-programmers level? like sending 1234 with midi, how would you break it down bitwise? thanks in advance
~/.jc _______________________________________________ Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> https://lists.puredata.info/listinfo/pd-list
hi list, Christof
THAT was very insightfull. big massive thanks.
On Thu, Jun 2, 2016, at 06:58 PM, Christof Ressi wrote:
Check this article as a starting point: https://en.wikipedia.org/wiki/Bit_manipulation
For breaking up and reassembling integers you only need bit shifting and bit masking. Bit masking is needed to get rid of unwanted bits. For example:
Mask some byte: 1 0 1 0 0 1 1 0 (your data) & 0 0 0 0 1 1 1 1 (your mask) = 0 0 0 0 0 1 1 0 (result)
How to make your mask:
(1 << 4) is 16 (00010000) (1 << 4)-1 is 15 (00001111) - here you go!
So the formular for making a mask where the rightmost N bits are all 1 is
(1 << N)-1
Now here's a simple example of how to break up a 16-bit integer into three 7-bit values:
unsigned char buf[3]; // buffer for three bytes int a = 1234; // your integer, in binary it's 0000 0100 1101 0010 const unsigned char m = (1 << 7)-1; // a 7-bit mask
a &= (1 << 16)-1; // clip beyond 16 bit, just to be sure
buf[0] = a & m; // get the 7 rightmost bit by masking, in this case 101 0010 (= 82) buf[1] = (a >> 7) & m; // shift 7 bits to the right and mask, in this case 000 1001 (= 9) buf[2] = (a >> 14) & m; // shift 2*7 bits to the right and mask, in this case 000 0000 (= 0)
or with a loop:
for (int i = 0; i < 3; ++i){ buf[i] = (a >> i*7) & m; }
Now the other way round:
unsigned char buf[3] = {82, 9, 0}; // integer 1234 broken up into three 7-bit values int a = 0; // integer to be reassembled
a += (int) buf[0]; // just 82 a += (int) buf[1] << 7; // 9 shifted 7 bits to the left is 1152 a += (int) buf[2] << 14; // 0 shifted 14 bits to the left is 0
/* a is now 82 + 1152 = 1234 */
or with a loop:
for (int i = 0; i < 3; ++i){ a += (int) buf[i] << i*7; // make sure to first cast the unsigned char (byte) to an integer before shifting it to the left!!! }
As you see, working with 7-bit data is actually quite neat. Just check if incoming bytes are bigger than 127 to distinguish between 'system messages' and actual data. This way it's quite simple to build your own little protocol.
Christof
Gesendet: Donnerstag, 02. Juni 2016 um 14:53 Uhr Von: "jamal crawford" threen52@ml1.net An: pd-list@lists.iem.at, danomatika@gmail.com Betreff: Re: [PD] Pduino sysex vs. OSC advice (Christof Ressi)
hi list
If you need a greater resolution for your values, just break them up into several bytes. This way, sending > a single 16 bit integer would take 4 bytes (address, bit 14-15, bit 13-7, bit 0-6).
That’s a great point. Everyone complains about MIDI now (not enough range, etc) but it’s *perfect* for >what it was designed to do: send small event data quickly on much older, slower hardware. I little >bitmasking and away you go.
i second that! very neat point indeed. would it be to much to ask if anyone could clarify that bitmasking to a lower, non-programmers level? like sending 1234 with midi, how would you break it down bitwise? thanks in advance
~/.jc _______________________________________________ Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> https://lists.puredata.info/listinfo/pd-list