Bits and Bytes - richardjwild/arctracker GitHub Wiki
Following on from the previous effort, I wasn't very happy with the code in the pianola_roll function, specifically this part:
printf(
"%s %c%c%X%X | ",
notes[event.note],
alphanum[event.sample],
alphanum[event.effects[0].code + 1],
(event.effects[0].data >> 4) & 0xf,
event.effects[0].data & 0xf);
so I refactored it to this:
channel_event_t event = line[track];
effect_t first_effect = event.effects[0];
printf(
"%s %c%c%X%X | ",
notes[event.note],
alphanum[event.sample],
alphanum[first_effect.code + 1],
high_nybble(first_effect.data),
low_nybble(first_effect.data));
which involved extracting two functions:
static inline
int low_nybble(const __uint8_t octet)
{
return octet & 0xf;
}
static inline
int high_nybble(const __uint8_t octet)
{
return (octet >> 4) & 0xf;
}
But I had already defined macros that did a similar job in other modules. This had clearly become a function in its own right, so I created a new header file called bits.h to give a home for all this stuff. I converted the low_nybble and high_nybble functions to macros and put all of them in there:
#define MASK_AND_SHIFT_RIGHT(value, mask, shift) \
(((unsigned int) (value) >> (unsigned int) (shift)) & (unsigned int) (mask))
#define MASK_5_SHIFT_RIGHT(value, shift) \
(__uint8_t) MASK_AND_SHIFT_RIGHT(value, 0x1f, shift)
#define MASK_6_SHIFT_RIGHT(value, shift) \
(__uint8_t) MASK_AND_SHIFT_RIGHT(value, 0x3f, shift)
#define MASK_8_SHIFT_RIGHT(value, shift) \
(__uint8_t) MASK_AND_SHIFT_RIGHT(value, 0xff, shift)
#define HIGH_NYBBLE(value) \
(__uint8_t) MASK_AND_SHIFT_RIGHT(value, 0xf, 4)
#define LOW_NYBBLE(value) \
(__uint8_t) MASK_AND_SHIFT_RIGHT(value, 0xf, 0)
That was a very simple job, but worth doing.