@@ -44,9 +44,11 @@ struct fake_device {
4444 pattern.reserve (pattern_samples * n_channels);
4545 for (auto sample_ix = 0 ; sample_ix < pattern_samples; ++sample_ix) {
4646 for (auto chan_ix = 0 ; chan_ix < n_channels; ++chan_ix) {
47+ // sin(2*pi*f*t), where f cycles from 1 Hz to Nyquist: srate / 2
48+ double f = (chan_ix + 1 ) % (int )(srate / 2 );
4749 pattern.emplace_back (
4850 offset_0 + chan_ix * offset_step +
49- magnitude * static_cast <int16_t >(sin (M_PI * chan_ix * sample_ix / n_channels )));
51+ magnitude * static_cast <int16_t >(sin (2 * M_PI * f * sample_ix / srate )));
5052 }
5153 }
5254 last_time = std::chrono::steady_clock::now ();
@@ -64,15 +66,15 @@ struct fake_device {
6466 return output;
6567 }
6668
67- std::size_t get_data (std::vector<int16_t > &buffer) {
69+ std::size_t get_data (std::vector<int16_t > &buffer, bool nodata = false ) {
6870 auto now = std::chrono::steady_clock::now ();
6971 auto elapsed_nano =
7072 std::chrono::duration_cast<std::chrono::nanoseconds>(now - last_time).count ();
7173 int64_t elapsed_samples = std::size_t (elapsed_nano * srate * 1e-9 ); // truncate OK.
7274 elapsed_samples = std::min (elapsed_samples, (int64_t )(buffer.size () / n_channels));
73- if (false ) {
75+ if (nodata ) {
7476 // The fastest but no patterns.
75- memset (&buffer[0 ], 23 , buffer.size () * sizeof buffer[0 ]);
77+ // memset(&buffer[0], 23, buffer.size() * sizeof buffer[0]);
7678 } else {
7779 std::size_t end_sample = head + elapsed_samples;
7880 std::size_t nowrap_samples = std::min (pattern_samples - head, elapsed_samples);
@@ -96,24 +98,28 @@ int main(int argc, char **argv) {
9698 std::string name{argc > 1 ? argv[1 ] : " MyAudioStream" }, type{argc > 2 ? argv[2 ] : " Audio" };
9799 int samplingrate = argc > 3 ? std::stol (argv[3 ]) : 44100 ; // Here we specify srate, but typically this would come from the device.
98100 int n_channels = argc > 4 ? std::stol (argv[4 ]) : 2 ; // Here we specify n_chans, but typically this would come from theh device.
99- int32_t max_buffered = argc > 5 ? std::stol (argv[5 ]) : 360 ;
101+ double max_buffered = argc > 5 ? std::stod (argv[5 ]) : 360 . ;
100102 int32_t chunk_rate = argc > 6 ? std::stol (argv[6 ]) : 10 ; // Chunks per second.
101103 int32_t chunk_samples = samplingrate > 0 ? std::max ((samplingrate / chunk_rate), 1 ) : 100 ; // Samples per chunk.
102104 int32_t chunk_duration = 1000 / chunk_rate; // Milliseconds per chunk
103105
104106 try {
105107 // Prepare the LSL stream.
106- lsl::stream_info info (name, type, n_channels, samplingrate, lsl::cf_int16);
107- lsl::stream_outlet outlet (info, 0 , max_buffered );
108+ lsl::stream_info info (
109+ name, type, n_channels, samplingrate, lsl::cf_int16, " example-SendDataInChunks " );
108110 lsl::xml_element desc = info.desc ();
109111 desc.append_child_value (" manufacturer" , " LSL" );
110112 lsl::xml_element chns = desc.append_child (" channels" );
111113 for (int c = 0 ; c < n_channels; c++) {
112114 lsl::xml_element chn = chns.append_child (" channel" );
113115 chn.append_child_value (" label" , " Chan-" + std::to_string (c));
114116 chn.append_child_value (" unit" , " microvolts" );
115- chn.append_child_value (" type" , " EEG " );
117+ chn.append_child_value (" type" , type );
116118 }
119+ int32_t buf_samples = max_buffered * samplingrate;
120+ lsl::stream_outlet outlet (info, chunk_samples, buf_samples);
121+ info = outlet.info (); // Refresh info with whatever the outlet captured.
122+ std::cout << " Stream UID: " << info.uid () << std::endl;
117123
118124 // Create a connection to our device.
119125 fake_device my_device (n_channels, (float )samplingrate);
@@ -126,7 +132,8 @@ int main(int argc, char **argv) {
126132
127133 // Your device might have its own timer. Or you can decide how often to poll
128134 // your device, as we do here.
129- auto next_chunk_time = std::chrono::high_resolution_clock::now ();
135+ auto t_start = std::chrono::high_resolution_clock::now ();
136+ auto next_chunk_time = t_start;
130137 for (unsigned c = 0 ;; c++) {
131138 // wait a bit
132139 next_chunk_time += std::chrono::milliseconds (chunk_duration);
@@ -137,9 +144,10 @@ int main(int argc, char **argv) {
137144
138145 // send it to the outlet. push_chunk_multiplexed is one of the more complicated approaches.
139146 // other push_chunk methods are easier but slightly slower.
140- outlet.push_chunk_multiplexed (chunk_buffer.data (), returned_samples * n_channels, 0.0 , true );
147+ double ts = lsl::local_clock ();
148+ outlet.push_chunk_multiplexed (
149+ chunk_buffer.data (), returned_samples * n_channels, ts, true );
141150 }
142-
143151 } catch (std::exception &e) { std::cerr << " Got an exception: " << e.what () << std::endl; }
144152 std::cout << " Press any key to exit. " << std::endl;
145153 std::cin.get ();
0 commit comments