#include #include "../../include/lsl_cpp.h" #include #include #include #include #include #include #include #include #include #include #include using namespace std; // key stress constants int max_outlets = 15; // was 20 int max_inlets = 20; // was 30 int min_chunk_len_ms = 1; int max_chunk_len_ms = 100; int max_inlet_poll_interval_ms = 100; int inlet_max_failure_interval_ms = 2000; int outlet_max_failure_interval_ms = 2000; int inlet_min_failure_interval_ms = 1; int outlet_min_failure_interval_ms = 1; int max_outlet_duration = 10; int max_inlet_duration = 10; double spawn_inlet_interval = 0.5; double spawn_outlet_interval = 0.5; int max_srate = 1000; int max_channels = 10; int max_buffered = 6; // misc parameters int max_chunk_oversize_factor = 5; int max_samples = 10000000; lslboost::atomic num_outlets(0); lslboost::atomic num_inlets(0); // some random names, types and formats lsl::channel_format_t fmts[] = {lsl::cf_int8,lsl::cf_int16,lsl::cf_int32,lsl::cf_float32,lsl::cf_double64,lsl::cf_string}; const char *names[] = {"Test1","Test2","Test3","Test4"}; const char *types[] = {"EEG","Audio","MoCap"}; // set to true by the main program when we're ready to quit bool stop_inlet = false, stop_outlet = false, start_outlet = false; // initialize a sample with data template void init_sample(int numchan, vector &sample) { sample.resize(numchan); for (int c=0;c()(s.str())); try { // choose random parameters if desired double duration = (duration_ == 0.0) ? 1.0+rand()%(max_outlet_duration-1) : duration_; string name = name_.empty() ? names[rand()%(sizeof(names)/sizeof(names[0]))] : name_; string type = type_.empty() ? types[rand()%(sizeof(types)/sizeof(types[0]))] : type_; int numchan = (numchan_ == 0) ? 1+(rand()%(max_channels-1)) : numchan_; double srate = (srate_ == 0.0) ? 1.0 + (rand()%(max_srate-1)) : srate_; lsl::channel_format_t fmt = (fmt_ == lsl::cf_undefined) ? fmts[rand()%6] : fmt_; double seconds_between_failures = (seconds_between_failures_ == 0.0) ? (inlet_min_failure_interval_ms+rand()%outlet_max_failure_interval_ms)/1000.0 : seconds_between_failures_; int chunk_len = (chunk_len_ == 0) ? std::max(min_chunk_len_ms,(rand()%max_chunk_len_ms)) : chunk_len_; // create a new streaminfo lsl::stream_info info(name,type,numchan,srate,fmt,lslboost::uuids::to_string(lslboost::uuids::random_generator()())); // initialize data to send vector chunk; init_sample((int)(numchan*floor(chunk_len*srate/1000*max_chunk_oversize_factor)),chunk); // and run... for (double endtime = lsl::local_clock()+duration;lsl::local_clock()fail_at) break; target = (int)floor((now-start_time)*srate); int num_elements = (int)std::min((std::size_t)((target-written)*numchan),chunk.size()); if (num_elements) outlet.push_chunk_multiplexed(&chunk[0],num_elements); diff = num_elements/numchan; } } cout << "del outlet(" << name << "," << type << "," << numchan << "," << fmt << "," << srate << ")" << endl; // downtime lslboost::this_thread::sleep(lslboost::posix_time::millisec(100*(rand()%50))); } } catch(std::exception &e) { std::cerr << "ERROR during run_outlet() Stress-test function: " << e.what() << std::endl; } num_outlets.fetch_sub(1); } // run an inlet for some time (optionally with sporadic interruptions in between) void run_inlet(const double duration_=0.0, const string name_=string(), const string type_=string(), const int in_chunks_=-1, const int request_info_=-1, const int request_time_=-1, const double seconds_between_failures_=0.0) { num_inlets.fetch_add(1); std::ostringstream s; s << lslboost::this_thread::get_id(); srand((unsigned)lslboost::hash()(s.str())); try { // choose random parameters if desired double duration = (duration_ == 0.0) ? 1.0+rand()%(max_outlet_duration-1) : duration_; string name = name_.empty() ? names[rand()%(sizeof(names)/sizeof(names[0]))] : name_; string type = type_.empty() ? types[rand()%(sizeof(types)/sizeof(types[0]))] : type_; int request_info = (request_info_==-1) ? rand()%3 == 0 : request_info_; int request_time = (request_time_==-1) ? rand()%3 == 0 : request_time_; double seconds_between_failures = (seconds_between_failures_ == 0.0) ? (inlet_min_failure_interval_ms+rand()%outlet_max_failure_interval_ms)/1000.0 : seconds_between_failures_; // resolve by type... vector results = lsl::resolve_stream("type",type,1,5); if (results.empty()) throw lsl::lost_error("No stream found."); lsl::stream_info result = results[rand()%results.size()]; vector chunk; // and run... double t=0.0; for (double endtime = lsl::local_clock()+duration;lsl::local_clock()1 && string(argv[1]) == "-f") || tolower(cin.get()) == 'y') { lslboost::thread outlets(&random_outlets,0.0,0.0,string(),string(),0,lsl::cf_undefined,0.0,0.0,0); lslboost::thread inlets(&random_inlets,0.0,0.0,string(),string(),-1,-1,-1,0.0); cout << "Press ENTER to exit. " << endl; cin.get();cin.get(); } return 0; }