gnuplot Real Time Plotting C Implementation - c

I'm completely new to gnuplot and have only learned the basics to start plotting. I'm writing a C program that does DSP and needs to plot the result in real time. In addition, I've setup my program in such following manner to incorporate the plot '-' feature from gnuplot. The parent process will perform the DSP computation constantly, and sends the result to the child using pipe in real time. The child will receive a signal from parent, wake up, and sends the result to gnuplot via pipe.
Basically, the path of data goes as such:
Parent(Computation) -> Pipe -> Child (Wait on Input from parent) -> Pipe -> gnuplot (Plotting)
For example, in the child, enclosed in a conditional wait
getline(&lineBuffer, lineSize, stdin);
printf("%s", lineBuffer);
fflush(stdout);
where lineBuffer can be any arbitrary char*, will redirect data from parent to gnuplot. I have all the necessary data for plotting, and it can be formatted in any format. However, after trying the following, there has been no success.
If not yet defined appearances and label,
set terminal x11 persist noraise
set xlabel "Frequency"
set ylabel "Decibel"
set xrange [0:2000]
set yrange [-100:100]
set style data lines
Start initial plot command,
plot '-' using 1:2 smooth unique
Start sending data, each point is a new line, where I formatted my data to be
Frequency Decibel
at a particular time, for example
1000 -30.00
1001 -31.00
....
End data by sending
e\n
Then I restart the process sending the data, and end it with
replot
Does this seem right? On the other hand, I'm also interested in plotting the time series of a particular frequency, and after numerous searches, apparently I need a buffer or a temporary file to accomplish this, is that correct also?

Related

Differentiate clipboard event when using read() function in c from stdin

I am working on terminal based text editor and stuck at a point where I need to differentiate whether the input text from read() function is a clipboard paste text or a keyboard text input.
#include <unistd.h>
char read_key_input() {
char ch;
int read_count;
while ((read_count = read(STDIN_FILENO, &ch, 1)) != 1)
{
// Handle error if any
}
return ch;
}
...
Edit: Here's what I ended up doing.
void read_key_input(void (*callback)(int)) {
char* text = malloc(UINT8_MAX);
int read_count;
while ((read_count = read(STDIN_FILENO, text, UINT8_MAX)) == -1)
{
// Handle error if any
}
// Handle escape sequences if found and return early
...
if (read_count > 1) {
// It's probably a clipboard text. So change the editor mode to input and loop through all the characters one by one.
else {
// It's a user keyboard text input
}
// Revert back to the original editor mode if changed
}
I updated the code to retrieve more than one byte at a time (as suggested by #AnttiHaapala) and process each byte. Seems to be sufficient for my text editor's need for now. Will post back if I update.
Usually you can differentiate this by counting the number of characters you've received in rapid succession. So if you get the keypresses more rapidly than say 1000 characters per minute, then it is likely a clipboard paste... or nonsense.
Furthermore, if you've set the terminal to raw mode, then you can easily monitor individual keypresses. Also make read accept more than one byte at once - with read that is the maximum number of bytes to receive without blocking when available anyway.
One example of such an interactive terminal program would be IPython - here two lines typed separately:
In [1]: print("Hello")
Hello
In [2]: print("World")
World
And here pasted in one go:
In [3]: print("Hello")
...: print("World")
...:
Hello
World
Notice how the prompt is different, and the program runs only after there has been a separate Enter key hit after a small delay.
AFAIK, you cannot do what you want (reliably).
The clipboard is related (usually) to some display server, e.g. Xorg or Wayland server (Weston). And X11 might have distant clients (hence, a clipboard operation could be slow, if crossing some ocean).
Some Linux machines (perhaps the web server at Stackoverflow) do not run any display server.
You could code a GUI application, e.g. using GTK or Qt.
You could test if your standard input is a terminal with termios(3) functions or isatty(3) (i.e. with isatty(STDIN_FILENO) or isatty(STDOUT_FILENO) for standard output)
If your program is run inside a crontab(1) job, or a unix pipeline, the standard input won't be a terminal, and there might not even be any display server running.
You could take inspiration from the source code of GNU emacs, which does detect when a display server is available (probably using environ(7), e.g. getenv(3) of "DISPLAY"...)
On Linux you might open(2) /dev/tty (see tty(4)) to access your terminal. In some cases, it does not exist.
Hey #jiten not sure if you checked like
its key input detect and check wether it's input is one by one key
or its instant bulk input.

Delete current terminal input line

I am trying to code a little console chat-program in C on linux.
So far I coded it in a way that both chatting partners are only able to alternately send/recv, because these function calls are blocking by default.
Now I would like to modify that program, so that both are able to send and receive simultaneously.
The problem that I find is, that once you typed some input to the terminal, I don't know how to output received messages, without messing up the current input line of the terminal.
If there was a way to delete that current input line, you could temporarily save that line, print the new message and put the input line right back.
However, I was not able to find a solution for this problem on the internet.
Is it possible to delete the current input line, and if not, how else could I achieve what I want?
I think you should look into ncurses as Edd said in his comment.
It would allow you to easily manage contents in your terminal window, which sounds like a good idea for your chat program.
All you'd need to do is store your messages in 2 character arrays:
char incoming[MSG_MAX]
and
char outgoing[MSG_MAX]
Then you can output those messages wherever you want in your terminal window, since ncurses allows you to specify x,y coordinates on where to put your text.
Then a simple wrapper for one of ncurses erase() family functions would allow you to delete characters from specify x,y coordinates in your terminal window.
Edit: MSG_MAX is not an actual ncurses macro.

read line of file in realtime in C

I know how to do basic file operations in C, but what I'd like to do if it is possible is somehow create a variable that represents a live running file (for example, an access_log from apache that updates every second). Then I want to be able to read the last line that is entered into the file as it happens regardless of whether any other process currently has the file open or not.
I'm thinking of code like this:
int main(){
FILE *live=fattachto("/path/to/apaches/access_log");
long lastupdated=live->lastwrite();
while(1){
if(live->lastwrite() != lastupdated){printf("File was just updated now\n");}
sleep(1);
}
}
Yes I did put in sleep in my code because I want to ensure my code doesn't oveheat the cpu.
and the code above as-is won't execute because I'm looking for the correct set of functions to use to produce the end result.
Any idea?
Why don't you just set line buffering or use small buffer read size, once you've seeked to the end of the log file? Then simply do blocking reads on the lines from the file as they're added?
Then when the read returns, you can signal, set flags or initiate processing, on any interesting input.

How to know from within a Fortran code if a file is opened by any program (Windows 7)

I have a Fortran code that updates in real time the content of a text file by adding some new real time measuraments at the very bottom of it. This text file is used (reading only) both by a fluid dynamics code (that continuously runs in real time) and by another executable built from matlab code (that performs plotting). I want to add a line in the Fortran code that says: update the text file ONLY IF it is not opened by any other program. I tried using INQUIRE:
do
INQUIRE(FILE = filename,OPENED = ISopen)
if (.not.ISopen) then
ADD NEW MEASUREMENTS HERE
exit
endif
endif
enddo
and before running this fortran program I opened the file with textpad. However, the variable ISopen is false. So I guess maybe INQUIRE only works for testing if file is opened within the fortran program itself. In fact if I add at the beginning of the above snippet of code:
OPEN (33,FILE = filename)
then ISopen is true. I then created an executable from a fortran code containing only:
OPEN (33,FILE = filename)
pause
CLOSE(33)
and I run it and let it in a paused status. I then run the first code I posted above and ISopen is still false. Any idea how to test if a file is open by any other program from within Fortran? My operative system is windows 7.
thanks
At the end I solved in this way. I could not find a way to know if the file is opened, and even if there was a way it could still happen that some other program opens it right between the time I check if its open and then I modify it. Therefore, I just create a temporary copy of the file to modify, I modify this temporary copy and then I move the file back by overwriting the original one. The latter operation is performed only if the file is not locked (i.e. no other program opened the file to read the data), so I keep trying to copy it until it succeeds. I tested in many situations and it works. The code is:
USE IFPORT
IMPLICIT NONE
character*256 :: DOScall
logical :: keepTRYING
integer :: resul
DOScall = 'copy D:\myfile.txt D:\myfile_TMP.txt' !create temporary copy
resul = SYSTEM(DOScall)
open(15,file ='D:\myfile_TMP.txt',form = 'formatted')
!.... perform here some writing operations on myfile_TMP........
close(15)
do
resul = SYSTEM('move D:\myfile_TMP.txt D:\myfile.txt')
if (resul==0) then
exit
else
pause(10)
endif
enddo
Note that works perfectly fine for multiple programs performing reading and one program writing in the file (as in my case where I have 2 programs reading and only one writing). If multiple programs write the same file I guess some other parallel techniques have to be used.
I do not think it is possible to check if a file is opened by an external process. Some programming languages allow you to check if the file is locked or not, and that is still far from telling you if the file is opened or not, both program must acquire and release system lock for it to really work. To my knowledge, the standard fortran does not have that feature directly, but you can use the semaphore from C with the interoperability stuff.
Most user application (editors mostly) however, before updating a file, usually check if the content on the disk has changed since they capture a copy, and alert the user. They also do that if they lost and acquire the focus. If you restrict your goal to updating only if the content has not changed since you opened it, you can do the same or simply open-add and close any time you want to add a new entry. A good editor will notify the user on the other side that the content had been change by another process.
An alternative is to simulate a lock yourself and buffer the data in fortran. By buffering I mean, collect some new data (let say 100, 1000 or whatever number that is convenient) and send them to the file at once. For each update, you open, update and close the file.
Your lock can be made of two simple files (emptys one for example), one created by the reader (matlab) and the other created by writer (fortran program). Let name them reading.ongoing for the reader and writing.ongoing for the writer.
On the fortran side, you do the following anytime you have collected enough data to write:
check for the existence of reading.ongoing (using inquire function), proceed only if it does not exist
create writing.ongoing
check for the existence of reading.ongoing again, if it exists, delete writing.ongoing and go back to step 1. If it does not exist, proceed forward.
open, write the data and close the data file
delete writing.ongoing
On matlab side, do similar thing, inverting the role of reading.ongoing and writing.ongoing.
In an exceptional race condition you could be blocked because they are all trying at the same time. In that case, you could modify the step 1. of matlab to force it to wait for few millisecond before proceeding. This will get you on the road as long as none of the program get killed between step 1 and 5.
You can also use semaphore with the interoperability stuff in fortran. See the following post for example. You can also similar think on the side of matlab, I do not have any example. That will lower your headhache and let the system manage the lock for you.

Detect if FFmpeg is running or has stopped running

I'm using C to scan a directory which contains frames extracted by ffmpeg. Now in the event that the last file is reached during the scan, I need to check for two conditions:
It's the last file as the video duration is over.
It's the last file as ffmpeg terminated abruptly and is no longer able to populate the directory
My C program workflow is like:
while(<there exists files in the directory>)
{
// iterate over them and do something with each frame
}
// coming out of the loop means no more files available...so I need a if condition
if(<check if ffmpeg is stopped>) // <-- need to know what to put inside the condition
{
// start it again
}
else
{
// video is over, nothing more left to do
}
I'm thinking I can do this using Process ID of ffmpeg, but how would I get that info? Any other alternative way of checking if ffpmeg has stopped?
Some metadata
OS : Windows 7
IDE : Dev C++
Language Used : C
You can definitely wait for FFmpeg process to finish. You normally obtain ffmpeg.exe process handle and either wait for it using wait functions, check its GetExitCodeProcess or both.
If you don't have a handle, but you do have a process identifier, OpenProcess will get you the handle.
Of course, you would not have to go into that trouble if you used native Windows APIs where you would be dealing with frames directly, not through files and external processes.
Not sure if this is a way to go in your case, but... in unix world a program that runs in background normally creates a publicly readable file with its process id. And then removes it when finished.
You could create this file from your batch script and then in your C program you could check if a pid from that file is running or not.

Resources