/** * latenc.c * -------------------------------- * (c) Manuel Traut * 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 #include #include #include #include #include #include /** * 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_list){ latency = latency*1000; std::cout.precision(20); // latency already in list? for(std::list::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_list){ double avg = 0; int sum = 0; for(std::list::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"<::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_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::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"<* 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::iterator it = lat_list->begin(); it != lat_list->end(); it++){ if(display) std::cout<latency<<" "<counter<latency<<" "<counter<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 \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 [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* latencies1st; std::list* latencies2nd; val1 = new int; val2 = new int; val3 = new int; time = new float; latencies1st = new std::list; latencies2nd = new std::list; 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: "<"<<*val1< 0) ){ // if ref state changed refTimeUp = *time; if(debug) std::cout<<*time<<": ref Up: "<"<<*val1< 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: "< 0) && latStartUp ){ // see above! float latency2 = *time - refTimeUp; voltage2 = *val2; if(debug) std::cout<<*time<<": CH1 latency Up: "< 0) && (*val3 <= 0) && latStartDown ){ // see above! float latency3 = *time - refTimeDown; voltage3 = *val3; if(debug) std::cout<<*time<<": CH2 latency Down: "< 0) && latStartUp ){ // see above! float latency3 = *time - refTimeUp; voltage3 = *val3; if(debug) std::cout<<*time<<": CH2 latency Up: "<