Dictionary/LUT implementation in C - c

I have 500 frames for which I have stored the length of each frame in an array as the frames are in ascending order.
const char header_length = {23,34, 45, 12, 23,56,......,2,4};
Here frame 1 is of length 23 bytes, frame 2 is of length 34 bytes.
Now when I am requested frame with header 4 I would have to reply with frame with header 7, frame with header 8 would require a reply frame with header 60. The co-relation is a constant, header 4 frame will always reply header 7 frame. So I need a look up table sort of implementation here. I plan to implement this using a multidimensional array. Although is there a better way to implement this?

I am answering based on OP's comment above, otherwise OP's question just does not make any sense.
Assuming that the maximum frame size is limited by a considerably small N, then it may be better to just keep another array as the following,
const char header_length[] = {23,34, 45, 12, 23,56,......,2,4};
const int to_be_replied[N+1] = {...,0,...,2,...,0,...,4,...}; /* fill remaining */
/* here are their positions #12 #23 #34 #45 */
and use the following during the reply.
int frame_num, reply_frame_num;
frame_num = get_frame_number(); /* some function */
reply_frame_num = to_be_replied[header_length[frame_num]];

Related

Linux sound programming. How to determine a buffer size in frames?

I'm experimenting with ALSA and came across with the following configuration parameter in this howto, Section 2:
The unit of the buffersize depends on the function. Sometimes it is
given in bytes, sometimes the number of frames has to be specified.
One frame is the sample data vector for all channels. For 16 Bit
stereo data, one frame has a length of four bytes.
/* Set buffer size (in frames). The resulting latency is given by */
/* latency = periodsize * periods / (rate * bytes_per_frame) */
if (snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams, (periodsize * periods)>>2) < 0) {
fprintf(stderr, "Error setting buffersize.\n");
return(-1);
}
I don't understand this For 16 Bit stereo data, one frame has a length
of four bytes
Why is it four? Does it follow by the number of channels: 2? I mean earlier they configured it as follows:
/* Set number of channels */
if (snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 2) < 0) {
fprintf(stderr, "Error setting channels.\n");
return(-1);
}
How about if my acoustic system contains 4 outputs? Or 6? Does it mean that I have to configre it to 16 Bit * 4 and 16 Bit * 6 correspondingly?
Why is it four? Does it follow by the number of channels: 2?
Yes, according to mentioned earlier:
One frame is the sample data vector for all channels.
So for stereo 16 bit data, there are two (left and right) channels of 16 bits (=2 bytes) each, so that totals to 4 bytes per frame.

C: Write to a specific line in the text file without searching

Hello I have file with text:
14
5 4
45 854
14
4
47 5
I need to write a text to a specific line. For example to the line number 4 (Doesn't matter whether I will append the text or rewrite the whole line):
14
5 4
45 854
14 new_text
4
47 5
I have found function fseek(). But in the documentation is written
fseek(file pointer,offset, position);
"Offset specifies the number of positions (bytes) to be moved from the location specified bt the position."
But I do not know the number of bites. I only know the number of lines. How to do that? Thank you
You can't do that, (text) files are not line-addressable.
Also, you can't insert data in the middle of a file.
The best way is to "spool" to a new file, i.e. read the input line by line, and write that to a new file which is the output. You can then easily keep track of which line you're on, and do whatever you want.
I will assume that you are going to be doing this many times for a single file, as such you would be better indexing the position of each newline char, for example you could use a function like this:
long *LinePosFind(int FileDes)
{
long * LinePosArr = malloc(500 * sizeof(long));
char TmpChar;
long LinesRead = 0;
long CharsRead = 0;
while(1 == read(FileDes, &TmpChar, 1))
{
if (!(LinesRead % 500)
{
LinePosArr = realloc(LinePosArr, (LinesRead + 500) * sizeof(long));
}
if (TmpChar == '\n')
{
LinePosArr[LinesRead++] = CharsRead;
}
CharsRead++;
}
return LinePosArr;
}
Then you can save the index of all the newlines for repeated use.
After this you can use it like so:
long *LineIndex = LinePosFind(FileDes);
long FourthLine = LineIndex[3];
Note I have not checked this code, just written from my head so it may need fixes, also, you should add some error checking for the malloc and read and realloc if you are using the code in production.

zero padding a signal in MATLAB

I have an audio signal of length 12769. I'm trying to perform STFT on it by breaking it into small windows of 1024 samples. This gives me with 12 exact windows while there are 481 points remaining. Since i need 543 (1024 - 481) more points to make up 1024 samples, i used the following code to zero pad.
f = [a zeros(1,542)];
where a is the audio file.
However i get an error saying
??? Error using ==> horzcat
CAT arguments dimensions are not consistent.
How can I overcome this?
Your vector a is a column vector and cannot be concatenated with row vector zeros(1,542). Use zeros(542,1) instead.
However, it is much easier to just use
f = a;
f(1024*ceil(end/1024)) = 0;
MATLAB will zero pad the vector up to element 1024, and it is independent of the array being column or row.
You can either remove the excess 481 samples using
Total_Samples = length(a);
for i=1 : Total_Samples-481
a_new[i] = a[i];
or you could add an additional 543 Zero samples by using
Total_Samples = length(a);
for i=Total_Samples+1 : Total_Samples+543
a[i] = 0 ;

Wireless.h How do I print out the signal level?

Using wireless tools for linux in a c program, and I did a network scan wanting to find the signal strength (dBm) of each of the detected networks.
I found the following in the wireless.h:
struct iw_quality
{
__u8 qual; /* link quality (%retries, SNR,
%missed beacons or better...) */
__u8 level; /* signal level (dBm) */
__u8 noise; /* noise level (dBm) */
__u8 updated; /* Flags to know if updated */
};
I print out the "level" in my C program like this:
printf("Transmit power: %lu ", result->stats.qual.level);
also tried %d, but got the same output.
The result I get is numbers that look something like 178, 190, 201, 189 etc...
Is there a chance that these numbers are in Watts? According to a watt->dBm converter, 178 watts is approx. 52.50dBm ?
What should I be getting instead? Because I thought dBm translates to -80dBm or something.
Do I need to convert those numbers? How do I get the right output?
Thanks!!
=======UPDATE=========
I noticed some weird behaviour. When I use the level property of wireless.h through my program, the "strongest" value I have recorded is around -50dBm, whereas with the same router, when I ran "iw wlan0 scan", I receive around -14dBm as the strongest signal.
Does anyone know what causes this difference??
It looks like you found the right answer. For the record, this is what the source (iwlib.c) says about the encoding.
/* People are very often confused by the 8 bit arithmetic happening
* here.
* All the values here are encoded in a 8 bit integer. 8 bit integers
* are either unsigned [0 ; 255], signed [-128 ; +127] or
* negative [-255 ; 0].
* Further, on 8 bits, 0x100 == 256 == 0.
*
* Relative/percent values are always encoded unsigned, between 0 and 255.
* Absolute/dBm values are always encoded between -192 and 63.
* (Note that up to version 28 of Wireless Tools, dBm used to be
* encoded always negative, between -256 and -1).
*
* How do we separate relative from absolute values ?
* The old way is to use the range to do that. As of WE-19, we have
* an explicit IW_QUAL_DBM flag in updated...
* The range allow to specify the real min/max of the value. As the
* range struct only specify one bound of the value, we assume that
* the other bound is 0 (zero).
* For relative values, range is [0 ; range->max].
* For absolute values, range is [range->max ; 63].
*
* Let's take two example :
* 1) value is 75%. qual->value = 75 ; range->max_qual.value = 100
* 2) value is -54dBm. noise floor of the radio is -104dBm.
* qual->value = -54 = 202 ; range->max_qual.value = -104 = 152
*
* Jean II
*/
level and noise fall under example 2, and can be decoded with a cast to a signed 8 bit value.
For future record, this was resolved from the comments, thanks to the relevant people.
I simply needed to cast the unsigned int to a signed one and it was solved.
Changed the print line to this:
printf("Transmit power: %d ", (int8_t) result->stats.qual.level);
Now the values that looked like 178, 200 turned to -80, -69 etc!

Running Unreached code in C

Below is the a sample C Program which provides the output followed after the program
#include<stdio.h>
void newfunc(int n);
int main(void)
{
newfunc(2);
return 0;
}
void newfunc(int n)
{
printf("\n%d",n);
if(n<50)
{
newfunc(2*n);
printf("\n%d",n);
}
}
produces output
2
4
8
16
32
64
32
16
8
4
2
But according to the code, it seems that after the function call in line 13, the next printf is not called. And the output seems unnatural. I searched the internet and found something about stacks. Can someone elaborate why this happens?
This is a basic recursive call.
First, notice that for values of n less than 50 your function will print n twice, and for other values of n it will print only once. That agrees with your output,so the only thing to figure out here is the order...
Second notice that the output for n*2 should come between the first and second line of output from n (for n < 50), because you make the recursive call in between the two printfs. Well, that also agrees with your output.
This is as expected.
The part you found on the internet about stacks is referring to the call stack. In order to return from a function the program has to keep track of where it was when the function was called. This information is written to 'end' of a special part of memory called the "call stack" or "execution stack"; and it is taken off of the stack (meaning that the 'end' is moved when the function returns). Call parameters are also recorded on the stack.
This kind of stacking is essential to recursion.
So, when you call newfunc(2) the program records that it was on line 5, then jumps to the beginning of newfunc on line 8. The stack looks (notionally) like:
line 5, n=2
When it gets to line 13, it calls new function again, making the stack
line 5, n=2; line 13, n=4
This goes on several times until the stack looks like
line 5, n=2; line 13, n=4; line 13, n=8; line 13, n=16; line 13, n=32; line 13, n=64
when the if fails and newfunc returns poping the stack and resuming execution after line 13 (because that is what we got off the stack) making the stack
line 5, n=2; line 13, n=4; line 13, n=8; line 13, n=16; line 13, n=32
when we run printf and pop the stack as we return to line 13 (what we got when we popped, right>) so that the stack is
line 5, n=2; line 13, n=4; line 13, n=8; line 13, n=16;
and so on while it unwinds the whole call stack.
A couple of final details: the stack notionally grows "up" so we often write it as
line 13, n=32
line 13, n=16
line 13, n=8
line 13, n=4
line 5, n=2
and the exact format of the stuff of the stack depends on the architecture of the chip and some decisions made by the OS programmers.
BTW--a c program doesn't typically use line numbers to denote "where" it was because lines are not good measures in c (I can write the whole program one one line if I'm silly enough), rather it uses the value of a register on the chip, but that doesn't really affect the explanation here.
What actually happens is, when you call the function in line 13 the code after the function cannot execute at that time, so they are stored in a special place in memory called stacks and they are filled up from bottom so newer codes fill in the top of the stacks. So at the first function call the printf("\n%d",2) is added to the stack at the bottom and printf("\n%d",4); i.e, 2 * n = 2 * 2 = 4 is added to top of the previous stack and when the recursive execution stops. the stack program from top is executed producing the above complex type of output not predictable to simple analysis.
Lets take it for small value say 10
1st call from main ////returned from newfunc(2)
newfunc(2)
//inside newfunc(2)
print 2
2<10 (correct)
newfunc(4) --> on stack print 2 //returned from newfunc(4)
-------------------------------
//inside newfunc(4)
print 4
4<10
newfunc(8) --> on stack print 4 //returned from newfunc(8)
---------------------------------
//inside newfunc(8)
print 8
8<10
newfunc(16) --> on stack print 8 //returned from newfunc(16)
---------------------------
//inside newfunc(16)
print 16
16<10 failed
so it will return to its previous function whichever has called it so it will go on --> symbol which is top of stack here for this example and print is used to show the result on screen
Function sequence is top to down ... I tried to show this in diagram. hope you get it.
here --> statement will be executed from bottom to top so the result will be
2
4
8
16
8
4
2

Resources