Extracting a sequence of LSBs using a trigger sequence? - c

I just have a question with regards to extracting a sequence of LSBs from an audio file. I've embedded 580 bits in sequences of 58 in the audio file, each sequence is 1000 samples apart. The first 10 bits of the sequence are the trigger bits.
What I'm trying to do is go through all the audio samples and if there's a 10 bit sequence that matches the trigger bit sequence, extract the first bit of that sequence plus the next 57.
However, I am getting millions of bits extracted which is not correct since the max number of samples of this particular audio is 1.5 million.
I understand that there may be samples which matches the trigger sequence which weren't embedded but even then I didn't think it was possible to have 8 million bits extracted.
Below is my code and I would appreciate if anyone could shed any light to where I am going wrong?
int counter = 0;
bool startOfWatermark = 0;
int idxOfWatermarkStart = 0;
//goes through all the frames in the audio
for (int frames = 0; frames < maxFrames; frames++)
{
//checks if the LSB of a frame is = to 1st trigger bit
if ((outputFrames[frames] & 1) == 1){
counter = 0;
//check the next 10 bits to see if they match the trigger bits
for (int i = 0; i < 10; i++){
int idxToCheck = i + frames;
if ((outputFrames[idxToCheck] & 1) == triggerBits[i]){
counter++;
//if all 10 bits matches the trigger bits, set startOfWatermark to true and keep record of that frame position
if (counter == 10){
startOfWatermark = 1;
idxOfWatermarkStart = frames;
}
}
}
}
//write out the 58bits starting from the first trigger bit.
if (startOfWatermark){
for (int j = idxOfWatermarkStart; j < idxOfWatermarkStart + 58; j++){
fprintf(fp, "%d", outputFrames[j] & 1);
}
}
}

Related

Converting from pgm to pbm but getting wrong output

I've written a program that takes a PGM image as input and converts it to a PBM file. However, the image I get as output is incorrect.
I determine if a pixel is white if its value is bigger than (max+1)/2 then use putchar() to place the character with the value 0 and if its black 1(ive also tried max instead of 1 and 255). However, I get a bunch of vertical lines as output. I'm running this in a Linux terminal with the command :
./prog < image1.pgm > image2.pbm
This is the function I'm using to read and transform the image (where size is height and width, and max is the max value of each pixel):
void p5_to_p4(int size, int max){
int g1,g2,g3;
int i;
for(i=0; i<size; i++){
g1=getchar();
g2=getchar();
g3=getchar();
if (g1>((max+1)/2)){
putchar(0);
putchar(0);
putchar(0);
}
else {
putchar(max);
putchar(max);
putchar(max);
}
}
}
this is the output image im getting(in jpeg form): output when this is what i should be getting correct output
I've written a program that takes a PGM image as input and converts it to a PBM file. However, the image I get as output is incorrect.
Not surprising. Taking the function presented to be for converting a pixel raster from the format of NetPBM P5 ("PGM") to the pixel raster format of NetPBM P4 ("PBM"), the function has at least these issues:
PGM files can use either one-byte or two-byte samples, depending on the maximum sample value specified, but the function presented neither adapts to the maximum sample value nor assumes either of the two valid sample sizes. Instead, it assumes three-byte samples. Perhaps it is supposing three color channels, but PGM has only one.
PBM files use one byte per eight pixels, but the function outputs three bytes per one pixel.
So, first, read the samples correctly. In that regard, do note that if you have to handle two-byte samples then they are stored most-significant byte first, which is probably opposite to your machine's native byte order.
Second, you'll need to pack the output 8 one-bit samples per byte. Read the linked specs for details if you need them. Note that if the number of samples is not divisible by eight then you'll need to add one or more dummy bits to the last byte.
PBM file format packs 8 pixels into a byte in the order of msb first
and lsb last.
If the width of the image is not multiple of 8, the last odd pixels
are packed into a byte without wrapping around to the next line.
Then you need to let the function know width and height individually,
not the total size.
Then the converter function will look like:
void p5_to_p4(int width, int height, int max)
{
int g, b; // g for gray, b for binary
int i, j, k;
for (i = 0; i < height; i++) {
for (j = 0; j < width / 8; j++) {
b = 0;
for (k = 0; k < 8; k++) { // process 8 pixels at a time
g = getchar();
if (max > 255) { // in case of 2 bytes per pixel pgm
g = (g << 8) + getchar();
}
b <<= 1;
if (g < (max + 1) / 2) {
b |= 1; // raise the bit for a dark pixel
}
}
putchar(b);
}
if (width % 8) { // handle odd pixels, if any
b = 0;
for (k = 0; k < width % 8; k++) {
g = getchar();
if (max > 255) {
g = (g << 8) + getchar();
}
b <<= 1;
if (g < (max + 1) / 2) {
b |= 1;
}
}
b <<= 8 - width % 8; // justify to the msb
putchar(b);
}
}
}

Quick way to turn a binary array into a decimal string

I have a binary number, stored in an array of bytes (unsigned chars), and want to turn it into a decimal string.
The "obvious" approach that i found online was, to iterate over the array, add everything up while keeping track of the base and then converting it into a string but this doesn't work for me because the whole number doesn't fit into any common datatype and therefor cannot be added up in one go.
typedef unsigned char byte;
typedef struct Bin {
int size;
byte *ptrToVal;
} Bin;
void asDecString(Bin* this) {
signed int n = 0;
for(int i = 0; i < this->size; i++) {
n += this->ptrToVal[i] << (i * 8);
printf("%u\t%u\t%u\n", this->ptrToVal[i], n, i);
}
printf("%u\n", n);
}
The second, slow approach is to store the number in a string and multiply the digits in the string.
I'm looking for a quick way to implement this in c, but because I'm completely new to the language I don't know the features that well.
Out of curiosity and interest, here's my implementation of the algorithm found at:
https://my.eng.utah.edu/~nmcdonal/Tutorials/BCDTutorial/BCDConversion.html
It outputs intermediary values as each bit is processed. The verbose block can be moved out of the loop after testing.
Try it with one or two 'hex' bytes to begin with.
#include <stdio.h>
typedef unsigned char binByte;
void toBCD( binByte *p, int size ) {
const int decSize = 50; // Arbitrary limit of 10^49.
binByte decDgt[ decSize ]; // decimal digits as binary 'nibbles'.
int curPow10 = 0;
memset( decDgt, 0, sizeof(decDgt) );
for( int i = 0; i < size; i++ ) {
binByte oneByte = p[ i ]; // Initial one byte value
for( binByte bit = 0x80; bit > 0; bit >>= 1 ) {
for( int ii = 0; ii <= curPow10; ii++ )
if( decDgt[ ii ] >= 5 ) // Algorithm step
decDgt[ ii ] += 3;
for( ii = curPow10; ii >= 0; ii-- ) {
decDgt[ ii ] <<= 1;
if( decDgt[ ii ] & 0x10 ) { // Carry high bit?
decDgt[ ii + 1 ] |= 0x1;
if( ii == curPow10 ) // new power of 10?
curPow10++;
}
decDgt[ ii ] &= 0xF; // dealing in 'nibbles'
}
decDgt[ 0 ] |= ( (oneByte & bit) != 0 ); // truth value 0 or 1
printf( "Bottom: " );
for( ii = curPow10; ii >= 0; ii-- )
putchar( decDgt[ ii ] + '0' );
putchar( '\n' );
}
}
}
void main( void ) {
binByte x[] = { 0x01, 0xFF, 0xFF, 0xFF, 0xFF };
toBCD( x, sizeof(x) );
}
For large integers; you want to break them into "small enough integers", then convert the "small enough integers" into digits.
For example, lets say you have the number 1234567890. By doing next_piece = number / 100; number = number % 100; you could split it into pieces that fit in one byte, then print the smaller pieces 12, 34, 56, 78, 90 (with nothing between them and leading zeros to ensure the piece 03 doesn't get printed as 3) so that it looks like a single larger number.
In the same way you could split it into pieces that fit in a 32-bit unsigned integer; so that each piece is from 0 to 1000000000, by doing something like next_piece = number / 1000000000; number = number % 1000000000;. For example, the number 11223344556677889900112233445566778899 could be split into 11, 223344556, 677889900, 112233445, 566778899 and then printed (with leading zeros, etc).
Of course for big integers you'd need to implement a "divide by 1000000000" that works with your data structure, that returns a uint32_t (the remainder or the next piece) and the original value divided by 1000000000.
This is where things get messy. Using an array of bytes is slow, and signed numbers are painful. To fix that you'd want something more like:
#include <stdint.h>
typedef struct AlternativeBin {
int signFlag;
int size;
uint32_t *ptrToVal;
} AlternativeBin;
It wouldn't be hard to convert from your original format into this alternative format (if you can't just use this alternative format for everything).
The division loop would look something like (untested):
// WARNING: Destructive (the input value is used to return the quotient)
uint32_t getNextPiece(AlternativeBin * value) {
uint64_t temp = 0;
int i;
// Do the division
for(i = value->size - 1; i >= 0; i--) {
temp = (temp << 32) | value->ptrToVal[i];
value->ptrToVal[i] = temp / 1000000000ULL;
temp = temp % 1000000000ULL;
}
// Reduce the size of the array to improve performance next time
while( (value->size > 0) && (value->ptrToVal[value->size - 1] == 0) ) {
value->size--;
}
return temp;
}
..which means the "printing loop" (using recursion to reverse the order of pieces) might look like (untested):
#include <stdio.h>
#include <inttypes.h>
// WARNING: Recursive and destructive (the input value is destroyed)
void printPieces(AlternativeBin * value) {
uint32_t piece;
piece = getNextPiece(value);
if( !value_became_zero(value) ) {
printPieces(value);
printf("%09" PRIu32, piece); // Print it with leading zeros
} else {
printf("%" PRIu32, piece); // No leading zeros on first piece printed
}
}
The other minor inconvenience is that you'll want to print a '-' at the start if the value is negative (untested):
// WARNING: Destructive (the input value is destroyed)
void printValue(AlternativeBin * value) {
if(value->signFlag) {
printf("-");
}
printPieces(value);
}
If you wanted you could also create a copy of the original data here (get rid of the WARNING: Destructive comment by destroying a copy and leaving the original unmodified); and convert from your original structure (bytes) into the alternative structure (with uint32_t).
Note that it would be possible to do all of this with bytes (something like your original structure) using a divisor of 100 (instead of 1000000000). It'd just be a lot slower because the expensive getNextPiece() function will need to be called about 4.5 as many times.

Count bits set upto a given position for a 32 bit type

I am working with an algorithm that performs many popcount/sideways addition up to a given index for a 32 bit type. I am looking to minimize the operations required to perform what I have currently implemented as this:
int popcto_test1(unsigned int bitmap[], int idx){
int i = 0, // index
count = 0; // number of set bits
do {
// Each node contains 8 bitmaps
if(bitmap[i/32] & 1 << (i & 31)){
++count;
}
++i;
} while (i < idx);
return count;
}
I am aware of bit twiddling hacks for 64 bit types but there doesn't seem to be a fast way to do this for 32 bit types.
Is there a better (fewer operations / minimal branching) - or even just an alternative that I can try, ideally with a source?
I am aware (from reading similar posts) that such optimizations are usually not recommended but my project focuses on comparing performance differences of 'optimizations' - and whether they improve performance or not.
I've since run a bunch of performance benchmarks based on the suggested methods, and what I had above (tested 4,000,000 times) and got the following results:
avg popcto_test1 ns=133
avg popcto_test2 // test failed
avg popcto_test3 ns=28
avg popcto_test4 ns=74
where the test functions were as followed:
The failed test 2:
int popcto_test2(unsigned int bitmap[], int idx){
int i = 0, // index
count = 0; // number of set bits
do {
// Each node contains 8 bitmaps
count += (bitmap[i/32] & (1 << (i & 31)));
++i;
} while (i < idx);
return count;
}
popcto_test3 ns=28
One (perhaps) interesting point of note about this one is that although it is the fastest, if optimization levels 2 or 3 are used (-O2/-O3) the result it gives is incorrect.
int popcto_test3(unsigned int bitmap[], int idx){
int i = 0, // index
count = 0, // number of set bits
map = idx/32;
while (i < map){
// Each node contains 8 bitmaps
count += __builtin_popcount(bitmap[i]);
++i;
}
count += __builtin_popcount(bitmap[map] & ((1<<idx)-1));
return count;
}
avg popcto_test4 ns=74 (Modified Peter Wegner Method)
int popcto_test4(unsigned int bitmap[], int idx){
int i = 0, // index
j = 0,
count = 0, // number of set bits
map = idx/32;
unsigned int temp = 0;
while (i < map){
temp = bitmap[i];
j = 0;
while(temp){
temp &= temp - 1;
++j;
}
count += j;
++i;
}
temp = bitmap[i] & ((1<<idx)-1);
j = 0;
while(temp){
temp &= temp - 1;
++j;
}
return count + j;
}
Thanks everyone for the suggestions, I decided to pit all the methods I had come across head to head as I couldn't find any similar tests.
N.B. The population counts shown are for indexes up to argv[1], not a popcount of argv[1] - 8x 32-bit arrays make up 256 bits. The code used to produce these results can be seen here.
On my Ryzen 1700,For my usage, the fastest population count was (often) the one on page 180 of the Software Optimization Guide for AMD64 Processors. This (often) remains true for larger population counts too.
unsigned int population_count(int temp){
// Software Optimization Guide for AMD64 Processors - Page 180
temp = temp - ((temp >> 1) & 0x55555555);
temp = (temp & 0x33333333) + ((temp >> 2) & 0x33333333);
return (((temp + (temp >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
}
I don't have a side by side comparison for this but if you happen to be using CUDA; the intrinsic __popc method is the fastest, shortly followed by the wegner method. The AMD64 Method is the 2nd slowest (after bitwise only), I believe this is due to increased occupancy / register usage compared to all other methods.

C - number sorting description

I have written a C program which sorts an array of 50 of random numbers from 0 - 255. The highest number once sorted is displayed on 8 LEDs as binary digits. The same for the lowest sorted number. I fully understand the program however I need to write up a brief description of it and am struggling with these two functions:
void binaryLowesttNumber()
{
int remainder = lowArray; /* remainder is what I am going to be left with after taking away the value of the pins,
sets remainder as the lowest sorted number */
int j = 128; // value of pins in binary
int i = 7; // index of current pin
while (i >= 0)
{
if (remainder >= j) //if remainder is larger or equal to the value of the current pin
{
digitalWrite(pinArray[i], HIGH);
remainder = remainder - j; // takes value of pin away from remainder
j = j >> 1; // halves the value of j
i--; // moves to next pin
}
else
{
j = j >> 1; // halves the value of j
i--; // moves to next pin
}
}
}
void binaryHighestNumber()
{
int remainder = highArray; // same as binaryLowestNumber function except the remainder will be the highest sorted number
int i = 128;
int thisPin = 7;
while (remainder > 0)
{
while (remainder >= i)
{
double j = i / 2;
digitalWrite(pinArray[thisPin], HIGH);
remainder = remainder - i;
i = i - j;
thisPin--;
}
while (remainder < i)
{
int j = i / 2;
if (j >= 1)
{
i = i - j;
thisPin--;
}
else
{
i = 0;
}
}
}
}
Concentrate on what the function does (not on how it does that, your code explains that). What does function binaryHighestNumber() do? As I understood you correctly, your function sorts an array of 50 of random numbers from 0 - 255 and displays the highest number on 8 LEDs as binary digit. So a perfectly good and informative comment would be:
/**
* Sort an array of 50 random numbers from 0 - 255 and
* display the highest number on 8 LEDs as binary digit using 'digitalWrite()' function.
*/
void binaryHighestNumber()
...
Try to use doxygen format to document your code, that way it will be easy understandable by others who had worked with doxygen. And document what the function does, not how it does that. See Linux kernel coding commenting or GNU coding standard.
EDIT:
I don't see any sorting done in binaryHighestNumber() function. Are you sure this function sorts the array? As I inspect the function definition, all it does is to display a value stored in variable highArray on LEDs. Maybe a better comment would be this:
/**
* Display the highest number obtained from sorting array of 50 elements
* stored in a global variable 'highArray'
* on 8 LEDs as binary digit using 'digitalWrite()' function.
*/
void binaryHighestNumber()
...
EDIT2:
The intent was, that the question is how the code works and now how to comment it, so here we go. Let's concentrate on binaryHighestNumber().
Basically what the function does, is that it sets gpios high which number corresponds to the bit number in highArray. So for a highArray = 0b10101010 we want to light up gpios numbers 7, 5, 3 and 1 (numbering from 0). For highArray = 0b10100101 we want to light up gpios numbers 7, 5, 2 and 0.
The code binaryHighestNumber() keeps track of a remainder - the number substracted from the number of gpios already examined. The other is i - a value that is equal to 2 to the power of currently checked gpio number. thisPin is used to track the gpio number we currently check and it is equal to log2(i).
At first remainder = highArray and i = 128 and we want to check, if we should set gpio number 7 to high. We need to check if bit number 7 in the remainder is set or not. If the remainder is greater then 128, that means that the bit number 7 is set, that means that gpio number 7 needs to be set to high. If bit number 7 is not set, that means that remainder is lower then 128, we don't light the gpio. If the bit number 7 was set, we remove bit 7 from remainder (ie. substract i, which is eqaul to 128, from the remainder) and then bitshift i to the right by dividing it by 2. If bit number 7 was not set, we only bitshift i to the right.
Now remainder = highArray&0b01111111 and i = 64. We continue the process. If the remainder is greater than 64, that means that bit number 6 is set and we need to set gpio number 6 high, remove bit 6 from the remainder (by substracting i from it) and bitshift i to the left (by diving it by 2). If the number is lower then 64, we only bitshift i and continue.
Then remainder = highArray&0b00111111 and i = 32 and we continue until the remainder is equal to zero. (ie. remainder = highArray&0b00000000.
You can simplify the code, to somewhat easier form, like this:
void binaryHighestNumber()
{
int remainder = highArray; // same as binaryLowestNumber function except the remainder will be the highest sorted number
int i = 128;
int thisPin = 7;
while (remainder > 0) {
if (remainder >= i) {
digitalWrite(pinArray[thisPin--], HIGH);
remainder -= i;
i -= i/2;
}
if (remainder < i) {
if (i != 1) {
i -= i/2;
thisPin--;
} else {
i = 0;
}
}
}
}
or maybe like this:
void binaryHighestNumber()
{
int remainder = highArray; // same as binaryLowestNumber function except the remainder will be the highest sorted number
int i = 128;
int thisPin = 7;
while (remainder > 0) {
if (i != 0 && remainder >= i) {
digitalWrite(pinArray[thisPin--], HIGH);
remainder -= i;
i /= 2;
}
if (remainder < i) {
i /= 2;
thisPin--;
}
}
}
Pay attention to that i -= i/2; is not equal to i /= 2;, when i = 1. Also i have removed while loops, they don't change anything. I have removed j variables, they are not needed and don't change anything.
There is a much simpler way to check each bit in a byte and light up these gpios, but I think i will leave that to you to find out.

Incrementing integer from 0 becomes negative

I'm working on an embedded systems project where I'm trying to demodulate data from an IR sensor (which uses 'pulse width modulation'). The code below simply waits for the IR Sensor to start pulsing, and then measure the width (duration) of each high and low pulse.
In this code, I have a loop where I'm incrementing an integer:
irPulseSet irReadPulse()
{
irPulseSet outputPulseSet;
int pulseCount = 0;
int finished = 0;
while(1)
{
int lowPulse = 0;
int highPulse = 0;
while( bit_is_clear( irSensorPin , irSensorPinNo ) )
{
highPulse++;
_delay_us( 20 );
}
while( !bit_is_clear( irSensorPin , irSensorPinNo ) )
{
if ( lowPulse > 3250 )
{
finished = 1;
break;
}
lowPulse++;
_delay_us( 20 );
}
if ( finished )
break;
outputPulseSet.pulses[pulseCount][0] = highPulse * 20;
outputPulseSet.pulses[pulseCount][1] = lowPulse * 20;
pulseCount++;
}
// Assign pulse count to output pulse set
outputPulseSet.pulseCount = pulseCount;
return outputPulseSet;
}
Because this is an embedded systems project, and my resources are limited, I'm doing my debugging with an LCD display (as the circuit cannot be connected to a computer)
Printing each pulse
int irPrintPulses( irPulseSet pulseSet )
{
int counter;
for( counter = 0; counter <= pulseSet.pulseCount; counter++ )
{
LCDClearScreen();
char printStr[100];
sprintf( printStr , "H%iL%i;%i " , pulseSet.pulses[counter][0] , pulseSet.pulses[counter][1] , counter );
LCDSendString( printStr );
_delay_ms(1000);
}
_delay_ms(5000);
LCDClearScreen();
LCDSendString( "Finished pulse print!" );
_delay_ms(1000);
LCDClearScreen();
return 0;
}
The lowPulse int seems to sometimes be negative (eg value of -1054). I'm totally puzzled as it's first defined as 0 and all I ever do to it is increment it, so how can it become negative?
You have X bits to represent a number: 1 bit is for the signal and X - 1 bits is for the value
lets say you have a number that is represented with 4 bits:
0000 = 0
0001 = 1
...
0111 = 7
If you increment 1 here, you will change the first bit (the signal bit)
1000 = -8
Try the code bellow
#include <stdio.h>
#include <limits.h>
int main()
{
int i = INT_MAX;
printf("%d\n", i);
printf("%d\n", i + 1);
printf("%u\n", i + 1);
if(i > 0)
printf("greater\n");
i++;
if(i < 0)
printf("what kind of witchcraft is that?");
}
Once you add one after the maximum value it will flip to the maximum negative value, the 3rd printf is printing as an unsigned value (using the 1st bit not for the signal but for value)...
Since this is embedded I am going to assume that you are working with 16 bit integers. As a result, if you increment highPulse 32,768 times it will overflow and become negative. The value transitions from 0x7fff (positive) to 0x8000 (negative).
Given a delay loop of 20 usec, this will take 655.36 msec. Any time the first loop has to wait for this long for the bit to transition you will get negative numbers. I would have thought this is quite possible.
Do you have 32 bit longs? If so, the simplest solution is probably to use them for these counters. Then it will take about 40,000 seconds to overflow, which should be enough.

Resources