summaryrefslogtreecommitdiff
path: root/cdrom/tools/latencyTest/latenc.c
diff options
context:
space:
mode:
authorguest <guest@cba7306a-a4a0-4afd-bcb4-bd19f8a24309>2007-11-30 13:41:25 +0000
committerguest <guest@cba7306a-a4a0-4afd-bcb4-bd19f8a24309>2007-11-30 13:41:25 +0000
commiteacbf5bb4d57af21c731f41251015d3b991ad490 (patch)
tree477f43a79c75b400228a7c492f670a1c4886b5c3 /cdrom/tools/latencyTest/latenc.c
final version, initial import
git-svn-id: svn+ssh://mecka.net/home/svn/rtcorba-thesis@1 cba7306a-a4a0-4afd-bcb4-bd19f8a24309
Diffstat (limited to 'cdrom/tools/latencyTest/latenc.c')
-rwxr-xr-xcdrom/tools/latencyTest/latenc.c352
1 files changed, 352 insertions, 0 deletions
diff --git a/cdrom/tools/latencyTest/latenc.c b/cdrom/tools/latencyTest/latenc.c
new file mode 100755
index 0000000..77e3570
--- /dev/null
+++ b/cdrom/tools/latencyTest/latenc.c
@@ -0,0 +1,352 @@
+/**
+ * latenc.c
+ * --------------------------------
+ * (c) Manuel Traut <mail@manut.de>
+ * 06/11/08 - version 0.98
+ * --------------------------------
+ * This program is free software;
+ * you can redistribute it and/or
+ * modify it under the terms of
+ * the GNU General Public License
+ * Version 2 as published by the
+ * Free Software Foundation.
+**/
+
+#include <fstream>
+#include <stdlib.h>
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <math.h>
+#include <list>
+
+/**
+ * structure for latency-list
+ * --------------------------------
+ * 1st latency
+ * 2nd counter
+ */
+struct latency_counter{
+ float latency;
+ unsigned int counter;
+ latency_counter(float _latency){
+ counter = 1;
+ latency = _latency;
+ }
+} typedef lat_count;
+
+/**
+ * seperates values of one line
+ * convert time
+ * --------------------------------
+ * 1st time
+ * 2nd reference signal
+ * 3rd delayed signal
+ * 4th another delayed signal
+**/
+
+void sep_values(std::string cpp_string, float* time, int* val1, int* val2, int* val3){
+
+ int posStart = 0;
+ int posEnd = cpp_string.find(",", posStart);
+
+ std::string time_str = cpp_string.substr(posStart, posEnd);
+ int posOfExp = time_str.find("e", 0);
+ std::string expo = time_str;
+ std::string base = time_str.substr(0, posOfExp);
+ expo = expo.substr(posOfExp+1, expo.length());
+ float fbase = atof(base.c_str());
+ float fexpo = atof(expo.c_str());
+ *time = fbase*pow(10.0,fexpo);
+
+ posStart = posEnd+1;
+ posEnd = cpp_string.find(",", posStart)-1;
+
+ *val1 = atoi(cpp_string.substr(posStart, posEnd).c_str());
+
+ posStart = posEnd+2;
+ posEnd = cpp_string.find(",", posStart)-1;
+
+ if(posEnd > cpp_string.length()){
+
+ posEnd = cpp_string.length()-1;
+
+ *val2 = atoi(cpp_string.substr(posStart, posEnd).c_str());
+ *val3 = 0;
+
+ } else {
+
+ *val2 = atoi(cpp_string.substr(posStart, posEnd).c_str());
+
+ posStart = posEnd+2;
+ posEnd = cpp_string.find(",", posStart)-1;
+
+ if(posEnd < cpp_string.length()) posEnd = cpp_string.length()-1;
+ *val3 = atoi(cpp_string.substr(posStart, posEnd).c_str());
+ }
+}
+
+/**
+ * adds a latencie to a latency-
+ * counter-list
+ * --------------------------------
+ * 1st latency
+ * 2nd latencycounterlist
+ * ret counter state
+**/
+
+int add_latency(float latency, std::list<lat_count>* lat_list){
+
+ latency = latency*1000;
+
+ std::cout.precision(20);
+ // latency already in list?
+ for(std::list<lat_count>::iterator it = lat_list->begin(); it != lat_list->end(); it++){
+ if(it->latency == latency){
+ it->counter++;
+ return it->counter;
+ }
+ }
+ // add latency
+ lat_count new_lat_count(latency);
+ lat_list->push_back(new_lat_count);
+ return new_lat_count.counter;
+}
+
+/**
+ * calculates jitter of a latency-
+ * counter-list
+ * --------------------------------
+ * 1st latencycounterlist
+ * ret jitter
+**/
+
+float calc_jitter(std::list<lat_count>* lat_list){
+
+ double avg = 0;
+ int sum = 0;
+
+ for(std::list<lat_count>::iterator it = lat_list->begin(); it != lat_list->end(); it++){
+ avg += it->counter * it->latency;
+ sum += it->counter;
+ }
+ avg = (double)(avg/sum);
+ std::cout<<"Mittelwert:\t"<<avg<<" sec";
+
+ double jitter = 0;
+
+ for(std::list<lat_count>::iterator it = lat_list->begin(); it != lat_list->end(); it++){
+ jitter += ((it->latency-avg)*it->counter);
+ }
+ jitter = (double)(jitter/sum);
+
+ return (float)jitter;
+}
+
+/**
+ * calculates modalvalues and ranges
+ * of a latency-counter-list
+ * --------------------------------
+ * 1st latencycounterlist
+ * 2nd debug
+**/
+
+void calc_modal(std::list<lat_count>* lat_list, bool debug=false){
+
+ lat_count modal(0);
+ lat_count min(0);
+ min = *lat_list->begin();
+ lat_count max(0);
+ max = *lat_list->begin();
+
+ for(std::list<lat_count>::iterator it = lat_list->begin(); it != lat_list->end(); it++){
+ if(it->latency < min.latency){ // for difference min -> modal (best case)
+ min = *it;
+ }
+ if(it->latency > max.latency){ // for difference max -> modal (worst case)
+ max = *it;
+ }
+ if(it->counter>modal.counter){ // most occurences
+ modal = *it;
+ } else if (it->counter == modal.counter) { // if same occurence, lower value
+ if (it->latency < modal.latency){
+ modal = *it;
+ }
+ }
+ }
+ std::cout<<"\nModalwert:\t"<<modal.latency<<" sec - Haeufigkeit: "<< modal.counter;
+ std::cout<<"\nSpannweite:\t"<<min.latency-modal.latency<<" sec (best case)\n\t\t "<<max.latency-modal.latency<<" sec (worst case)\n";
+}
+
+/**
+ * prints out latency-counter-list
+ * --------------------------------
+ * 1st latencycounterlist
+ * 2nd debug
+**/
+
+void print_lat_count(std::list<lat_count>* lat_list, int* ch_counter, bool display=false){
+ int i = 0;
+ std::stringstream ss;
+ ss<<*ch_counter;
+ std::string file = "result"+ss.str()+".txt";
+ std::ofstream w(file.c_str());
+ if(!w.is_open()){
+ std::cerr<<"cannot write output file\n";
+ } else {
+ w.precision(20);
+ for(std::list<lat_count>::iterator it = lat_list->begin(); it != lat_list->end(); it++){
+ if(display) std::cout<<it->latency<<" "<<it->counter<<std::endl;
+ w<<it->latency<<" "<<it->counter<<std::endl;
+ i++;
+ }
+ if(i>0) *ch_counter = *ch_counter+1;
+ }
+}
+
+/**
+ * main routine
+ * --------------------------------
+ * 1st filename of the csv-file
+**/
+
+int main(int argc, char** argv){
+
+ if(argc < 2){
+ std::cout<<"\nlatenc by Manuel Traut <mail@manut.de>\n\ndraws a graphical visualization and some statistical informations about latencies out of a Tektronix TDS 3034B generated csv file\n\nPhysical Configuration:\nCH1: reference signal\nCH2: delayed signal \nCH3: (optional) delayed signal\n\nOsciloscope Configuration:\n1) measure\n2) delay \n3) save \n4) all channels \n5) to FDD\n\nSYNOPSIS:\nlatenc <TEKxxxx.CSV> [debug]\n\n";
+ return EXIT_FAILURE;
+ }
+
+ bool debug = false;
+
+ // open file
+ std::ifstream f(argv[1]);
+ if(!f.is_open()){
+ std::cerr<<"file open failed\n";
+ return EXIT_FAILURE;
+ }
+
+ std::string d = "debug";
+ if(argc > 2) if(d==(argv[2])){
+ debug = true;
+ }
+
+ // var decl
+ int* val1; // actual value reference signal
+ int* val2; // actual value 1st delayed signal
+ int* val3; // actual value 2nd delayed signal
+ int voltage1, voltage2, voltage3; // state of the signal (+/-)
+ float* time; // actual time (1st csv)
+ float refTimeDown, refTimeUp; // timestamp ref signal raised/falled
+
+ bool firstFound = true; // to find a proper start
+ bool latStartUp = false;
+ bool latStartDown = false;
+
+ std::string linenr; // one csv line
+
+ int ch_counter = 0;
+
+ std::list<lat_count>* latencies1st;
+ std::list<lat_count>* latencies2nd;
+
+ val1 = new int;
+ val2 = new int;
+ val3 = new int;
+ time = new float;
+
+ latencies1st = new std::list<lat_count>;
+ latencies2nd = new std::list<lat_count>;
+
+ while(!f.eof()){
+
+ getline(f, linenr);
+
+ if(!f.eof()){
+
+ sep_values(linenr, time, val1, val2, val3);
+
+ if(firstFound){ // to find a proper start
+
+ firstFound = false;
+ voltage1 = *val1;
+
+ } else {
+
+ if ( (voltage1 > 0) && (*val1 <= 0) ){ // if ref state changed
+
+ refTimeDown = *time;
+ if(debug) std::cout<<*time<<": ref Down: "<<voltage1<<"->"<<*val1<<std::endl;
+ voltage1 = *val1;
+ latStartDown = true;
+
+ } else if ( (voltage1 <= 0) && (*val1 > 0) ){ // if ref state changed
+
+ refTimeUp = *time;
+ if(debug) std::cout<<*time<<": ref Up: "<<voltage1<<"->"<<*val1<<std::endl;
+ voltage1 = *val1;
+ latStartUp = true;
+
+ }
+
+ if ( (voltage2 > 0) && (*val2 <= 0) && latStartDown ){ // if delayed state changed
+
+ float latency2 = *time - refTimeDown; // calc latency
+ voltage2 = *val2; // remember state
+ if(debug) std::cout<<*time<<": CH1 latency Down: "<<latency2<<std::endl;
+ if(latency2 != 0){ // may happen at begining of cvs
+ add_latency(latency2, latencies1st);
+ }
+
+ } else if ( (voltage2 <= 0) && (*val2 > 0) && latStartUp ){ // see above!
+
+ float latency2 = *time - refTimeUp;
+ voltage2 = *val2;
+ if(debug) std::cout<<*time<<": CH1 latency Up: "<<latency2<<std::endl;
+ if(latency2 != 0) add_latency(latency2, latencies1st);
+
+ }
+ if ( (voltage3 > 0) && (*val3 <= 0) && latStartDown ){ // see above!
+
+ float latency3 = *time - refTimeDown;
+ voltage3 = *val3;
+ if(debug) std::cout<<*time<<": CH2 latency Down: "<<latency3<<std::endl;
+ if(latency3 != 0) add_latency(latency3, latencies2nd);
+
+ } else if ( (voltage3 <= 0) && (*val3 > 0) && latStartUp ){ // see above!
+
+ float latency3 = *time - refTimeUp;
+ voltage3 = *val3;
+ if(debug) std::cout<<*time<<": CH2 latency Up: "<<latency3<<std::endl;
+ if(latency3 != 0) add_latency(latency3, latencies2nd);
+
+ }
+ }
+ }
+ }
+
+ delete val1;
+ delete val2;
+ delete val3;
+ delete time;
+
+ f.close();
+
+ std::cout<<"\n\ndelayed 1st\n---------------\n\n";
+ print_lat_count(latencies1st, &ch_counter, debug);
+ std::cout<<"\nJitter:\t\t"<<calc_jitter(latencies1st)<<" sec";
+ calc_modal(latencies1st, debug);
+
+ std::cout<<"\n\ndelayed 2nd\n---------------\n\n";
+ print_lat_count(latencies2nd, &ch_counter, debug);
+
+ if(ch_counter == 1){
+ system("sh lat.sh");
+ } else {
+ std::cout<<"\nJitter:\t\t"<<calc_jitter(latencies2nd)<<" sec";
+ calc_modal(latencies2nd, debug);
+ system("sh lats.sh");
+ }
+
+ return EXIT_SUCCESS;
+}