Skip to content

Commit 800c23d

Browse files
tstennercboulay
authored andcommitted
Add some testing programs
1 parent aebaa71 commit 800c23d

File tree

3 files changed

+117
-0
lines changed

3 files changed

+117
-0
lines changed

CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,12 @@ if(NOT WIN32 AND LSL_TOOLS)
345345
target_link_libraries(blackhole PRIVATE Threads::Threads)
346346
target_include_directories(blackhole PRIVATE "thirdparty/asio/")
347347
installLSLApp(blackhole)
348+
add_executable(spike testing/spike.cpp)
349+
target_link_libraries(spike PRIVATE lsl)
350+
installLSLApp(spike)
351+
add_executable(flood testing/flood.c)
352+
target_link_libraries(flood PRIVATE lsl)
353+
installLSLApp(flood)
348354
endif()
349355

350356
set(LSL_INSTALL_ROOT ${CMAKE_CURRENT_BINARY_DIR})

testing/flood.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#include <lsl_c.h>
2+
#include <signal.h>
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <string.h>
6+
#include <unistd.h>
7+
8+
static double start_t;
9+
static int64_t samples_pushed = 0;
10+
11+
void handle_signal(int signal) {
12+
double time = lsl_local_clock() - start_t;
13+
printf("%ld samples pushed in %fs, %d samples/s\n", samples_pushed, time,
14+
(int)(samples_pushed / time));
15+
if (signal == SIGTERM || signal == SIGINT) exit(0);
16+
start_t = lsl_local_clock();
17+
samples_pushed = 0;
18+
}
19+
20+
int main(int argc, char *argv[]) {
21+
signal(SIGTERM, handle_signal);
22+
signal(SIGINT, handle_signal);
23+
#ifdef SIGUSR1
24+
signal(SIGUSR1, handle_signal);
25+
#endif
26+
#ifdef SIGCONT
27+
signal(SIGCONT, handle_signal);
28+
#endif
29+
printf("LSL inlet stress tester. Sends [nchan] uint16 channels as fast as possible.\n");
30+
printf("Usage: %s [streamname] [nchan=56] [chunksize=500]\n", argv[0]);
31+
printf("Using lsl %d, lsl_library_info: %s\n\n", lsl_library_version(), lsl_library_info());
32+
33+
const char *name = argc > 1 ? argv[1] : "Flood";
34+
const int nchan = argc > 2 ? strtol(argv[2], NULL, 10) : 56;
35+
const int samples_per_chunk = argc > 3 ? strtol(argv[3], NULL, 10) : 500;
36+
const char uid[] = "325wqer4354";
37+
38+
/* declare a new streaminfo (name: SendDataC / argument 1, content type: EEG, 8 channels, 500
39+
* Hz, float values, some made-up device id (can also be empty) */
40+
lsl_streaminfo info = lsl_create_streaminfo(name, "Bench", nchan, 50000, cft_int16, uid);
41+
42+
/* make a new outlet (chunking: default, buffering: 360 seconds) */
43+
lsl_outlet outlet = lsl_create_outlet_ex(info, 0, 360, transp_sync_blocking);
44+
char *infoxml = lsl_get_xml(lsl_get_info(outlet));
45+
printf("Streaminfo: %s\n", infoxml);
46+
lsl_destroy_string(infoxml);
47+
48+
const int buf_elements = nchan * samples_per_chunk;
49+
int16_t *buf = malloc(buf_elements * 2);
50+
memset(buf, 0xab, buf_elements * sizeof(buf[0]));
51+
52+
printf("Now sending data...\n");
53+
start_t = lsl_local_clock();
54+
55+
for (int t = 0;; t++) {
56+
lsl_push_chunk_s(outlet, buf, buf_elements);
57+
samples_pushed += samples_per_chunk;
58+
}
59+
lsl_destroy_outlet(outlet);
60+
return 0;
61+
}

testing/spike.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include "lsl_cpp.h"
2+
#include <chrono>
3+
#include <iostream>
4+
#include <random>
5+
#include <cstdlib>
6+
#include <thread>
7+
8+
using namespace std::chrono_literals;
9+
10+
const char *channels[] = {"C3", "C4", "Cz", "FPz", "POz", "CPz", "O1", "O2"};
11+
12+
int main(int argc, char *argv[]) {
13+
int n_channels = argc > 1 ? std::stoi(argv[1]) : 200;
14+
int samplingrate = argc > 2 ? std::stoi(argv[2]) : 50000;
15+
int max_buffered = argc > 3 ? std::stoi(argv[3]) : 360;
16+
bool sync = argc > 4 ? std::stoi(argv[4]) > 0 : true;
17+
18+
try {
19+
lsl::stream_info info("Spike", "bench", n_channels, samplingrate, lsl::cf_int16, "Spike");
20+
lsl::stream_outlet outlet(
21+
info, 0, max_buffered, sync ? transp_sync_blocking : transp_default);
22+
23+
std::vector<int16_t> chunk(n_channels * samplingrate / 1000, 5);
24+
25+
const auto t_start = std::chrono::high_resolution_clock::now();
26+
auto next_sample_time = t_start;
27+
const auto time_per_chunk = std::chrono::microseconds(8 / samplingrate);
28+
29+
// send data forever
30+
std::cout << "Now sending data... " << std::endl;
31+
for (unsigned t = 0;; t++) {
32+
if (t % 3 == 0) {
33+
for (int s = 0; s < 5; ++s)
34+
outlet.push_chunk_multiplexed(chunk);
35+
// Wait until the next expected sample time.
36+
} else {
37+
for (int s = 0; s < 10; ++s) {
38+
outlet.push_sample(chunk.data());
39+
std::this_thread::sleep_for(100us);
40+
}
41+
}
42+
next_sample_time += time_per_chunk;
43+
std::this_thread::sleep_until(next_sample_time);
44+
}
45+
46+
} catch (std::exception &e) { std::cerr << "Got an exception: " << e.what() << std::endl; }
47+
std::cout << "Press any key to exit. " << std::endl;
48+
std::cin.get();
49+
return 0;
50+
}

0 commit comments

Comments
 (0)