|
1 |
| -#include "lsl_cpp.h" |
2 |
| -#include <iostream> |
3 |
| -#include <stdlib.h> |
4 |
| -#include <time.h> |
5 |
| -using namespace std; |
6 |
| - |
7 |
| -/** |
8 |
| - * This example program offers an 8-channel stream, float-formatted, that resembles EEG data. |
9 |
| - * The example demonstrates also how per-channel meta-data can be specified using the .desc() field |
10 |
| - * of the stream information object. |
11 |
| - * |
12 |
| - * Note that the timer used in the send loop of this program is not particularly accurate. |
13 |
| - */ |
14 |
| - |
15 |
| - |
16 |
| -const char *channels[] = {"C3", "C4", "Cz", "FPz", "POz", "CPz", "O1", "O2"}; |
17 |
| - |
18 |
| -int main(int argc, char *argv[]) { |
19 |
| - string name, type; |
20 |
| - if (argc != 3) { |
21 |
| - cout << "This opens a stream under some user-defined name and with a user-defined content " |
22 |
| - "type." |
23 |
| - << endl; |
24 |
| - cout << "Please enter the stream name and the stream type (e.g. \"BioSemi EEG\" (without " |
25 |
| - "the quotes)):" |
26 |
| - << endl; |
27 |
| - cin >> name >> type; |
28 |
| - } else { |
29 |
| - name = argv[1]; |
30 |
| - type = argv[2]; |
31 |
| - } |
32 |
| - |
33 |
| - try { |
34 |
| - |
35 |
| - // make a new stream_info (100 Hz) |
36 |
| - lsl::stream_info info(name, type, 8, 100, lsl::cf_float32, string(name) += type); |
37 |
| - |
38 |
| - // add some description fields |
39 |
| - info.desc().append_child_value("manufacturer", "BioSemi"); |
40 |
| - lsl::xml_element chns = info.desc().append_child("channels"); |
41 |
| - for (int k = 0; k < 8; k++) |
42 |
| - chns.append_child("channel") |
43 |
| - .append_child_value("label", channels[k]) |
44 |
| - .append_child_value("unit", "microvolts") |
45 |
| - .append_child_value("type", "EEG"); |
46 |
| - |
47 |
| - // make a new outlet |
48 |
| - lsl::stream_outlet outlet(info); |
49 |
| - |
50 |
| - // send data forever |
51 |
| - cout << "Now sending data... " << endl; |
52 |
| - double starttime = ((double)clock()) / CLOCKS_PER_SEC; |
53 |
| - for (unsigned t = 0;; t++) { |
54 |
| - |
55 |
| - // wait a bit and create random data |
56 |
| - while (((double)clock()) / CLOCKS_PER_SEC < starttime + t * 0.01) |
57 |
| - ; |
58 |
| - float sample[8]; |
59 |
| - for (int c = 0; c < 8; c++) sample[c] = (float)((rand() % 1500) / 500.0 - 1.5); |
60 |
| - |
61 |
| - // send the sample |
62 |
| - outlet.push_sample(sample); |
63 |
| - } |
64 |
| - |
65 |
| - } catch (std::exception &e) { cerr << "Got an exception: " << e.what() << endl; } |
66 |
| - cout << "Press any key to exit. " << endl; |
67 |
| - cin.get(); |
68 |
| - return 0; |
69 |
| -} |
| 1 | +#include "lsl_cpp.h" |
| 2 | +#include <iostream> |
| 3 | +#include <stdlib.h> |
| 4 | +#include <time.h> |
| 5 | +#include <array> |
| 6 | +using namespace std; |
| 7 | + |
| 8 | +/** |
| 9 | + * This example program offers an 8-channel stream, float-formatted, that resembles EEG data. |
| 10 | + * The example demonstrates also how per-channel meta-data can be specified using the .desc() field |
| 11 | + * of the stream information object. |
| 12 | + * |
| 13 | + * Note that the timer used in the send loop of this program is not particularly accurate. |
| 14 | + */ |
| 15 | + |
| 16 | + |
| 17 | +const char *channels[] = {"C3", "C4", "Cz", "FPz", "POz", "CPz", "O1", "O2"}; |
| 18 | + |
| 19 | +int main(int argc, char *argv[]) { |
| 20 | + string name, type; |
| 21 | + if (argc < 3) { |
| 22 | + cout << "This opens a stream under some user-defined name and with a user-defined content " |
| 23 | + "type." << endl; |
| 24 | + cout << "SendData Name Type n_channels[8] srate[100] max_buffered[360] sync[false] contig[true]" << endl; |
| 25 | + cout << "Please enter the stream name and the stream type (e.g. \"BioSemi EEG\" (without " |
| 26 | + "the quotes)):" |
| 27 | + << endl; |
| 28 | + cin >> name >> type; |
| 29 | + } else { |
| 30 | + name = argv[1]; |
| 31 | + type = argv[2]; |
| 32 | + } |
| 33 | + int n_channels = argc > 3 ? std::stol(argv[3]) : 8; |
| 34 | + n_channels = n_channels < 8 ? 8 : n_channels; |
| 35 | + int samplingrate = argc > 4 ? std::stol(argv[4]) : 100; |
| 36 | + int max_buffered = argc > 5 ? std::stol(argv[5]) : 360; |
| 37 | + bool sync = argc > 6 ? std::stol(argv[6]) > 0 : false; |
| 38 | + bool contig = argc > 7 ? std::stol(argv[7]) > 0 : true; |
| 39 | + |
| 40 | + try { |
| 41 | + |
| 42 | + // make a new stream_info (100 Hz) |
| 43 | + lsl::stream_info info(name, type, n_channels, samplingrate, lsl::cf_float32, string(name) += type); |
| 44 | + |
| 45 | + // add some description fields |
| 46 | + info.desc().append_child_value("manufacturer", "LSL"); |
| 47 | + lsl::xml_element chns = info.desc().append_child("channels"); |
| 48 | + for (int k = 0; k < n_channels; k++) |
| 49 | + chns.append_child("channel") |
| 50 | + .append_child_value("label", k < 8 ? channels[k] : "Chan-" + std::to_string(k+1)) |
| 51 | + .append_child_value("unit", "microvolts") |
| 52 | + .append_child_value("type", type); |
| 53 | + |
| 54 | + // make a new outlet |
| 55 | + lsl::stream_outlet outlet(info, 0, max_buffered, sync ? transp_sync_blocking : transp_default); |
| 56 | + |
| 57 | + // send data forever |
| 58 | + cout << "Now sending data... " << endl; |
| 59 | + double starttime = ((double)clock()) / CLOCKS_PER_SEC; |
| 60 | + |
| 61 | + // Initialize 2 discontiguous data arrays. |
| 62 | + vector<float> sample(8, 0.0); |
| 63 | + vector<float> extra(n_channels - 8, 0.0); |
| 64 | + if (contig) { |
| 65 | + // If this is contiguous mode (default) then we combine the arrays. |
| 66 | + sample.insert( |
| 67 | + sample.end(), |
| 68 | + make_move_iterator(extra.begin()), |
| 69 | + make_move_iterator(extra.end())); |
| 70 | + } |
| 71 | + // bytes is used in !contig mode because we need to know how big each buffer is. |
| 72 | + array<uint32_t, 2> bytes = {8 * sizeof(float), static_cast<uint32_t>((n_channels - 8) * sizeof(float))}; |
| 73 | + for (unsigned t = 0;; t++) { |
| 74 | + |
| 75 | + // wait a bit and create random data |
| 76 | + while (((double)clock()) / CLOCKS_PER_SEC < starttime + t * 0.01) |
| 77 | + ; |
| 78 | + for (int c = 0; c < 8; c++) sample[c] = (float)((rand() % 1500) / 500.0 - 1.5); |
| 79 | + |
| 80 | + // send the sample |
| 81 | + if (contig) |
| 82 | + outlet.push_sample(sample); |
| 83 | + else { |
| 84 | + // Advanced: Push set of discontiguous buffers. |
| 85 | + array<float *, 2> bufs = {sample.data(), extra.data()}; |
| 86 | + outlet.push_numeric_bufs(reinterpret_cast<const char **>(const_cast<const float**>(bufs.data())), |
| 87 | + bytes.data(), 2, lsl::local_clock(), true); |
| 88 | + } |
| 89 | + } |
| 90 | + |
| 91 | + } catch (exception &e) { cerr << "Got an exception: " << e.what() << endl; } |
| 92 | + cout << "Press any key to exit. " << endl; |
| 93 | + cin.get(); |
| 94 | + return 0; |
| 95 | +} |
0 commit comments