diff --git a/LSL.cs b/LSL.cs index bb68473086a8fc2b4aa00f2b0721d6682d4a6ee2..b16151f8a8e3e59a6bbb5de59c4316914d94e28d 100644 --- a/LSL.cs +++ b/LSL.cs @@ -16,1235 +16,1253 @@ using System.Collections; * (for recording, viewing or experiment control). * */ -namespace LSL +namespace LSL { + +public class liblsl { - public class liblsl + /** + * Constant to indicate that a stream has variable sampling rate. + */ + public const double IRREGULAR_RATE = 0.0; + + /** + * Constant to indicate that a sample has the next successive time stamp. + * This is an optional optimization to transmit less data per sample. + * The stamp is then deduced from the preceding one according to the stream's sampling rate + * (in the case of an irregular rate, the same time stamp as before will is assumed). + */ + public const double DEDUCED_TIMESTAMP = -1.0; + + + /** + * A very large time duration (> 1 year) for timeout values. + * Note that significantly larger numbers can cause the timeout to be invalid on some operating systems (e.g., 32-bit UNIX). + */ + public const double FOREVER = 32000000.0; + + /** + * Data format of a channel (each transmitted sample holds an array of channels). + */ + public enum channel_format_t : byte + { + cf_float32 = 1, // For up to 24-bit precision measurements in the appropriate physical unit + // (e.g., microvolts). Integers from -16777216 to 16777216 are represented accurately. + cf_double64 = 2, // For universal numeric data as long as permitted by network & disk budget. + // The largest representable integer is 53-bit. + cf_string = 3, // For variable-length ASCII strings or data blobs, such as video frames, + // complex event descriptions, etc. + cf_int32 = 4, // For high-rate digitized formats that require 32-bit precision. Depends critically on + // meta-data to represent meaningful units. Useful for application event codes or other coded data. + cf_int16 = 5, // For very high rate signals (40Khz+) or consumer-grade audio + // (for professional audio float is recommended). + cf_int8 = 6, // For binary signals or other coded data. + // Not recommended for encoding string data. + cf_int64 = 7, // For now only for future compatibility. Support for this type is not yet exposed in all languages. + // Also, some builds of liblsl will not be able to send or receive data of this type. + cf_undefined = 0 // Can not be transmitted. + }; + + /** + * Post-processing options for stream inlets. + */ + public enum processing_options_t : byte + { + post_none = 0, // No automatic post-processing; return the ground-truth time stamps for manual post-processing + // (this is the default behavior of the inlet). + post_clocksync = 1, // Perform automatic clock synchronization; equivalent to manually adding the time_correction() value + // to the received time stamps. + post_dejitter = 2, // Remove jitter from time stamps. This will apply a smoothing algorithm to the received time stamps; + // the smoothing needs to see a minimum number of samples (30-120 seconds worst-case) until the remaining + // jitter is consistently below 1ms. + post_monotonize = 4, // Force the time-stamps to be monotonically ascending (only makes sense if timestamps are dejittered). + post_threadsafe = 8, // Post-processing is thread-safe (same inlet can be read from by multiple threads); uses somewhat more CPU. + post_ALL = 1 | 2 | 4 | 8// The combination of all possible post-processing options. + }; + + /** + * Protocol version. + * The major version is protocol_version() / 100; + * The minor version is protocol_version() % 100; + * Clients with different minor versions are protocol-compatible with each other + * while clients with different major versions will refuse to work together. + */ + public static int protocol_version() { return dll.lsl_protocol_version(); } + + /** + * Version of the liblsl library. + * The major version is library_version() / 100; + * The minor version is library_version() % 100; + */ + public static int library_version() { return dll.lsl_library_version(); } + + /** + * Obtain a local system time stamp in seconds. The resolution is better than a millisecond. + * This reading can be used to assign time stamps to samples as they are being acquired. + * If the "age" of a sample is known at a particular time (e.g., from USB transmission + * delays), it can be used as an offset to local_clock() to obtain a better estimate of + * when a sample was actually captured. See stream_outlet::push_sample() for a use case. + */ + public static double local_clock() { return dll.lsl_local_clock(); } + + + + + // ========================== + // === Stream Declaration === + // ========================== + + /** + * The stream_info object stores the declaration of a data stream. + * Represents the following information: + * a) stream data format (#channels, channel format) + * b) core information (stream name, content type, sampling rate) + * c) optional meta-data about the stream content (channel labels, measurement units, etc.) + * + * Whenever a program wants to provide a new stream on the lab network it will typically first + * create a stream_info to describe its properties and then construct a stream_outlet with it to create + * the stream on the network. Recipients who discover the outlet can query the stream_info; it is also + * written to disk when recording the stream (playing a similar role as a file header). + */ + + public class StreamInfo + { + /** + * Construct a new StreamInfo object. + * Core stream information is specified here. Any remaining meta-data can be added later. + * @param name Name of the stream. Describes the device (or product series) that this stream makes available + * (for use by programs, experimenters or data analysts). Cannot be empty. + * @param type Content type of the stream. Please see https://github.com/sccn/xdf/wiki/Meta-Data (or web search for: + * XDF meta-data) for pre-defined content-type names, but you can also make up your own. + * The content type is the preferred way to find streams (as opposed to searching by name). + * @param channel_count Number of channels per sample. This stays constant for the lifetime of the stream. + * @param nominal_srate The sampling rate (in Hz) as advertised by the data source, if regular (otherwise set to IRREGULAR_RATE). + * @param channel_format Format/type of each channel. If your channels have different formats, consider supplying + * multiple streams or use the largest type that can hold them all (such as cf_double64). + * @param source_id Unique identifier of the device or source of the data, if available (such as the serial number). + * This is critical for system robustness since it allows recipients to recover from failure even after the + * serving app, device or computer crashes (just by finding a stream with the same source id on the network again). + * Therefore, it is highly recommended to always try to provide whatever information can uniquely identify the data source itself. + */ + public StreamInfo(string name, string type) { obj = dll.lsl_create_streaminfo(name, type, 1, IRREGULAR_RATE, channel_format_t.cf_float32, ""); } + public StreamInfo(string name, string type, int channel_count) { obj = dll.lsl_create_streaminfo(name, type, channel_count, IRREGULAR_RATE, channel_format_t.cf_float32, ""); } + public StreamInfo(string name, string type, int channel_count, double nominal_srate) { obj = dll.lsl_create_streaminfo(name, type, channel_count, nominal_srate, channel_format_t.cf_float32, ""); } + public StreamInfo(string name, string type, int channel_count, double nominal_srate, channel_format_t channel_format) { obj = dll.lsl_create_streaminfo(name, type, channel_count, nominal_srate, channel_format, ""); } + public StreamInfo(string name, string type, int channel_count, double nominal_srate, channel_format_t channel_format, string source_id) { obj = dll.lsl_create_streaminfo(name, type, channel_count, nominal_srate, channel_format, source_id); } + public StreamInfo(IntPtr handle) { obj = handle; } + + /// Destroy a previously created streaminfo object. + ~StreamInfo() { dll.lsl_destroy_streaminfo(obj); } + + // ======================== + // === Core Information === + // ======================== + // (these fields are assigned at construction) + + /** + * Name of the stream. + * This is a human-readable name. For streams offered by device modules, it refers to the type of device or product series + * that is generating the data of the stream. If the source is an application, the name may be a more generic or specific identifier. + * Multiple streams with the same name can coexist, though potentially at the cost of ambiguity (for the recording app or experimenter). + */ + public string name() { return Marshal.PtrToStringAnsi(dll.lsl_get_name(obj)); } + + + /** + * Content type of the stream. + * The content type is a short string such as "EEG", "Gaze" which describes the content carried by the channel (if known). + * If a stream contains mixed content this value need not be assigned but may instead be stored in the description of channel types. + * To be useful to applications and automated processing systems using the recommended content types is preferred. + * Content types usually follow those pre-defined in https://github.com/sccn/xdf/wiki/Meta-Data (or web search for: XDF meta-data). + */ + public string type() { return Marshal.PtrToStringAnsi(dll.lsl_get_type(obj)); } + + /** + * Number of channels of the stream. + * A stream has at least one channel; the channel count stays constant for all samples. + */ + public int channel_count() { return dll.lsl_get_channel_count(obj); } + + /** + * Sampling rate of the stream, according to the source (in Hz). + * If a stream is irregularly sampled, this should be set to IRREGULAR_RATE. + * + * Note that no data will be lost even if this sampling rate is incorrect or if a device has temporary + * hiccups, since all samples will be recorded anyway (except for those dropped by the device itself). However, + * when the recording is imported into an application, a good importer may correct such errors more accurately + * if the advertised sampling rate was close to the specs of the device. + */ + public double nominal_srate() { return dll.lsl_get_nominal_srate(obj); } + + /** + * Channel format of the stream. + * All channels in a stream have the same format. However, a device might offer multiple time-synched streams + * each with its own format. + */ + public channel_format_t channel_format() { return dll.lsl_get_channel_format(obj); } + + /** + * Unique identifier of the stream's source, if available. + * The unique source (or device) identifier is an optional piece of information that, if available, allows that + * endpoints (such as the recording program) can re-acquire a stream automatically once it is back online. + */ + public string source_id() { return Marshal.PtrToStringAnsi(dll.lsl_get_source_id(obj)); } + + + // ====================================== + // === Additional Hosting Information === + // ====================================== + // (these fields are implicitly assigned once bound to an outlet/inlet) + + /** + * Protocol version used to deliver the stream. + */ + public int version() { return dll.lsl_get_version(obj); } + + /** + * Creation time stamp of the stream. + * This is the time stamp when the stream was first created + * (as determined via local_clock() on the providing machine). + */ + public double created_at() { return dll.lsl_get_created_at(obj); } + + /** + * Unique ID of the stream outlet instance (once assigned). + * This is a unique identifier of the stream outlet, and is guaranteed to be different + * across multiple instantiations of the same outlet (e.g., after a re-start). + */ + public string uid() { return Marshal.PtrToStringAnsi(dll.lsl_get_uid(obj)); } + + /** + * Session ID for the given stream. + * The session id is an optional human-assigned identifier of the recording session. + * While it is rarely used, it can be used to prevent concurrent recording activitites + * on the same sub-network (e.g., in multiple experiment areas) from seeing each other's streams + * (assigned via a configuration file by the experimenter, see Network Connectivity in the LSL wiki). + */ + public string session_id() { return Marshal.PtrToStringAnsi(dll.lsl_get_session_id(obj)); } + + /** + * Hostname of the providing machine. + */ + public string hostname() { return Marshal.PtrToStringAnsi(dll.lsl_get_hostname(obj)); } + + + // ======================== + // === Data Description === + // ======================== + + /** + * Extended description of the stream. + * It is highly recommended that at least the channel labels are described here. + * See code examples on the LSL wiki. Other information, such as amplifier settings, + * measurement units if deviating from defaults, setup information, subject information, etc., + * can be specified here, as well. Meta-data recommendations follow the XDF file format project + * (github.com/sccn/xdf/wiki/Meta-Data or web search for: XDF meta-data). + * + * Important: if you use a stream content type for which meta-data recommendations exist, please + * try to lay out your meta-data in agreement with these recommendations for compatibility with other applications. + */ + public XMLElement desc() { return new XMLElement(dll.lsl_get_desc(obj)); } + + /** + * Retrieve the entire stream_info in XML format. + * This yields an XML document (in string form) whose top-level element is <info>. The info element contains + * one element for each field of the stream_info class, including: + * a) the core elements <name>, <type>, <channel_count>, <nominal_srate>, <channel_format>, <source_id> + * b) the misc elements <version>, <created_at>, <uid>, <session_id>, <v4address>, <v4data_port>, <v4service_port>, <v6address>, <v6data_port>, <v6service_port> + * c) the extended description element <desc> with user-defined sub-elements. + */ + public string as_xml() + { + IntPtr pXml = dll.lsl_get_xml(obj); + string strXml = Marshal.PtrToStringAnsi(pXml); + dll.lsl_destroy_string(pXml); + return strXml; + } + + + /** + * Get access to the underlying handle. + */ + public IntPtr handle() { return obj; } + + private IntPtr obj; + } + + + // ======================= + // ==== Stream Outlet ==== + // ======================= + + /** + * A stream outlet. + * Outlets are used to make streaming data (and the meta-data) available on the lab network. + */ + public class StreamOutlet + { + /** + * Establish a new stream outlet. This makes the stream discoverable. + * @param info The stream information to use for creating this stream. Stays constant over the lifetime of the outlet. + * @param chunk_size Optionally the desired chunk granularity (in samples) for transmission. If unspecified, + * each push operation yields one chunk. Inlets can override this setting. + * @param max_buffered Optionally the maximum amount of data to buffer (in seconds if there is a nominal + * sampling rate, otherwise x100 in samples). The default is 6 minutes of data. + */ + public StreamOutlet(StreamInfo info) { obj = dll.lsl_create_outlet(info.handle(), 0, 360); } + public StreamOutlet(StreamInfo info, int chunk_size) { obj = dll.lsl_create_outlet(info.handle(), chunk_size, 360); } + public StreamOutlet(StreamInfo info, int chunk_size, int max_buffered) { obj = dll.lsl_create_outlet(info.handle(), chunk_size, max_buffered); } + + /** + * Destructor. + * The stream will no longer be discoverable after destruction and all paired inlets will stop delivering data. + */ + ~StreamOutlet() { dll.lsl_destroy_outlet(obj); } + + + // ======================================== + // === Pushing a sample into the outlet === + // ======================================== + + /** + * Push an array of values as a sample into the outlet. + * Each entry in the vector corresponds to one channel. + * @param data An array of values to push (one for each channel). + * @param timestamp Optionally the capture time of the sample, in agreement with local_clock(); if omitted, the current time is used. + * @param pushthrough Optionally whether to push the sample through to the receivers instead of buffering it with subsequent samples. + * Note that the chunk_size, if specified at outlet construction, takes precedence over the pushthrough flag. + */ + public void push_sample(float[] data) { dll.lsl_push_sample_ftp(obj, data, 0.0, 1); } + public void push_sample(float[] data, double timestamp) { dll.lsl_push_sample_ftp(obj, data, timestamp, 1); } + public void push_sample(float[] data, double timestamp, bool pushthrough) { dll.lsl_push_sample_ftp(obj, data, timestamp, pushthrough ? 1 : 0); } + public void push_sample(double[] data) { dll.lsl_push_sample_dtp(obj, data, 0.0, 1); } + public void push_sample(double[] data, double timestamp) { dll.lsl_push_sample_dtp(obj, data, timestamp, 1); } + public void push_sample(double[] data, double timestamp, bool pushthrough) { dll.lsl_push_sample_dtp(obj, data, timestamp, pushthrough ? 1 : 0); } + public void push_sample(int[] data) { dll.lsl_push_sample_itp(obj, data, 0.0, 1); } + public void push_sample(int[] data, double timestamp) { dll.lsl_push_sample_itp(obj, data, timestamp, 1); } + public void push_sample(int[] data, double timestamp, bool pushthrough) { dll.lsl_push_sample_itp(obj, data, timestamp, pushthrough ? 1 : 0); } + public void push_sample(short[] data) { dll.lsl_push_sample_stp(obj, data, 0.0, 1); } + public void push_sample(short[] data, double timestamp) { dll.lsl_push_sample_stp(obj, data, timestamp, 1); } + public void push_sample(short[] data, double timestamp, bool pushthrough) { dll.lsl_push_sample_stp(obj, data, timestamp, pushthrough ? 1 : 0); } + public void push_sample(char[] data) { dll.lsl_push_sample_ctp(obj, data, 0.0, 1); } + public void push_sample(char[] data, double timestamp) { dll.lsl_push_sample_ctp(obj, data, timestamp, 1); } + public void push_sample(char[] data, double timestamp, bool pushthrough) { dll.lsl_push_sample_ctp(obj, data, timestamp, pushthrough ? 1 : 0); } + public void push_sample(string[] data) { dll.lsl_push_sample_strtp(obj, data, 0.0, 1); } + public void push_sample(string[] data, double timestamp) { dll.lsl_push_sample_strtp(obj, data, timestamp, 1); } + public void push_sample(string[] data, double timestamp, bool pushthrough) { dll.lsl_push_sample_strtp(obj, data, timestamp, pushthrough ? 1 : 0); } + + + // =================================================== + // === Pushing an chunk of samples into the outlet === + // =================================================== + + /** + * Push a chunk of samples into the outlet. Single timestamp provided. + * @param data A rectangular array of values for multiple samples. + * @param timestamp Optionally the capture time of the most recent sample, in agreement with local_clock(); if omitted, the current time is used. + * The time stamps of other samples are automatically derived based on the sampling rate of the stream. + * @param pushthrough Optionally whether to push the chunk through to the receivers instead of buffering it with subsequent samples. + * Note that the chunk_size, if specified at outlet construction, takes precedence over the pushthrough flag. + */ + public void push_chunk(float[,] data) { dll.lsl_push_chunk_ftp(obj, data, (uint)data.Length, 0.0, 1); } + public void push_chunk(float[,] data, double timestamp) { dll.lsl_push_chunk_ftp(obj, data, (uint)data.Length, timestamp, 1); } + public void push_chunk(float[,] data, double timestamp, bool pushthrough) { dll.lsl_push_chunk_ftp(obj, data, (uint)data.Length, timestamp, pushthrough ? 1 : 0); } + public void push_chunk(double[,] data) { dll.lsl_push_chunk_dtp(obj, data, (uint)data.Length, 0.0, 1); } + public void push_chunk(double[,] data, double timestamp) { dll.lsl_push_chunk_dtp(obj, data, (uint)data.Length, timestamp, 1); } + public void push_chunk(double[,] data, double timestamp, bool pushthrough) { dll.lsl_push_chunk_dtp(obj, data, (uint)data.Length, timestamp, pushthrough ? 1 : 0); } + public void push_chunk(int[,] data) { dll.lsl_push_chunk_itp(obj, data, (uint)data.Length, 0.0, 1); } + public void push_chunk(int[,] data, double timestamp) { dll.lsl_push_chunk_itp(obj, data, (uint)data.Length, timestamp, 1); } + public void push_chunk(int[,] data, double timestamp, bool pushthrough) { dll.lsl_push_chunk_itp(obj, data, (uint)data.Length, timestamp, pushthrough ? 1 : 0); } + public void push_chunk(short[,] data) { dll.lsl_push_chunk_stp(obj, data, (uint)data.Length, 0.0, 1); } + public void push_chunk(short[,] data, double timestamp) { dll.lsl_push_chunk_stp(obj, data, (uint)data.Length, timestamp, 1); } + public void push_chunk(short[,] data, double timestamp, bool pushthrough) { dll.lsl_push_chunk_stp(obj, data, (uint)data.Length, timestamp, pushthrough ? 1 : 0); } + public void push_chunk(char[,] data) { dll.lsl_push_chunk_ctp(obj, data, (uint)data.Length, 0.0, 1); } + public void push_chunk(char[,] data, double timestamp) { dll.lsl_push_chunk_ctp(obj, data, (uint)data.Length, timestamp, 1); } + public void push_chunk(char[,] data, double timestamp, bool pushthrough) { dll.lsl_push_chunk_ctp(obj, data, (uint)data.Length, timestamp, pushthrough ? 1 : 0); } + public void push_chunk(string[,] data) { dll.lsl_push_chunk_strtp(obj, data, (uint)data.Length, 0.0, 1); } + public void push_chunk(string[,] data, double timestamp) { dll.lsl_push_chunk_strtp(obj, data, (uint)data.Length, timestamp, 1); } + public void push_chunk(string[,] data, double timestamp, bool pushthrough) { dll.lsl_push_chunk_strtp(obj, data, (uint)data.Length, timestamp, pushthrough ? 1 : 0); } + + /** + * Push a chunk of multiplexed samples into the outlet. One timestamp per sample is provided. + * @param data A rectangular array of values for multiple samples. + * @param timestamps An array of timestamp values holding time stamps for each sample in the data buffer. + * @param pushthrough Optionally whether to push the chunk through to the receivers instead of buffering it with subsequent samples. + * Note that the chunk_size, if specified at outlet construction, takes precedence over the pushthrough flag. + */ + public void push_chunk(float[,] data, double[] timestamps) { dll.lsl_push_chunk_ftnp(obj, data, (uint)data.Length, timestamps, 1); } + public void push_chunk(float[,] data, double[] timestamps, bool pushthrough) { dll.lsl_push_chunk_ftnp(obj, data, (uint)data.Length, timestamps, pushthrough ? 1 : 0); } + public void push_chunk(double[,] data, double[] timestamps) { dll.lsl_push_chunk_dtnp(obj, data, (uint)data.Length, timestamps, 1); } + public void push_chunk(double[,] data, double[] timestamps, bool pushthrough) { dll.lsl_push_chunk_dtnp(obj, data, (uint)data.Length, timestamps, pushthrough ? 1 : 0); } + public void push_chunk(int[,] data, double[] timestamps) { dll.lsl_push_chunk_itnp(obj, data, (uint)data.Length, timestamps, 1); } + public void push_chunk(int[,] data, double[] timestamps, bool pushthrough) { dll.lsl_push_chunk_itnp(obj, data, (uint)data.Length, timestamps, pushthrough ? 1 : 0); } + public void push_chunk(short[,] data, double[] timestamps) { dll.lsl_push_chunk_stnp(obj, data, (uint)data.Length, timestamps, 1); } + public void push_chunk(short[,] data, double[] timestamps, bool pushthrough) { dll.lsl_push_chunk_stnp(obj, data, (uint)data.Length, timestamps, pushthrough ? 1 : 0); } + public void push_chunk(char[,] data, double[] timestamps) { dll.lsl_push_chunk_ctnp(obj, data, (uint)data.Length, timestamps, 1); } + public void push_chunk(char[,] data, double[] timestamps, bool pushthrough) { dll.lsl_push_chunk_ctnp(obj, data, (uint)data.Length, timestamps, pushthrough ? 1 : 0); } + public void push_chunk(string[,] data, double[] timestamps) { dll.lsl_push_chunk_strtnp(obj, data, (uint)data.Length, timestamps, 1); } + public void push_chunk(string[,] data, double[] timestamps, bool pushthrough) { dll.lsl_push_chunk_strtnp(obj, data, (uint)data.Length, timestamps, pushthrough ? 1 : 0); } + + + // =============================== + // === Miscellaneous Functions === + // =============================== + + /** + * Check whether consumers are currently registered. + * While it does not hurt, there is technically no reason to push samples if there is no consumer. + */ + public bool have_consumers() { return dll.lsl_have_consumers(obj)>0; } + + /** + * Wait until some consumer shows up (without wasting resources). + * @return True if the wait was successful, false if the timeout expired. + */ + public bool wait_for_consumers(double timeout) { return dll.lsl_wait_for_consumers(obj)>0; } + + /** + * Retrieve the stream info provided by this outlet. + * This is what was used to create the stream (and also has the Additional Network Information fields assigned). + */ + public StreamInfo info() { return new StreamInfo(dll.lsl_get_info(obj)); } + + private IntPtr obj; + } + + + // =========================== + // ==== Resolve Functions ==== + // =========================== + + /** + * Resolve all streams on the network. + * This function returns all currently available streams from any outlet on the network. + * The network is usually the subnet specified at the local router, but may also include + * a multicast group of machines (given that the network supports it), or list of hostnames. + * These details may optionally be customized by the experimenter in a configuration file + * (see Network Connectivity in the LSL wiki). + * This is the default mechanism used by the browsing programs and the recording program. + * @param wait_time The waiting time for the operation, in seconds, to search for streams. + * Warning: If this is too short (less than 0.5s) only a subset (or none) of the + * outlets that are present on the network may be returned. + * @return An array of stream info objects (excluding their desc field), any of which can + * subsequently be used to open an inlet. The full info can be retrieve from the inlet. + */ + public static StreamInfo[] resolve_streams() { return resolve_streams(1.0); } + public static StreamInfo[] resolve_streams(double wait_time) + { + IntPtr[] buf = new IntPtr[1024]; int num = dll.lsl_resolve_all(buf, (uint)buf.Length, wait_time); + StreamInfo[] res = new StreamInfo[num]; + for (int k = 0; k < num; k++) + res[k] = new StreamInfo(buf[k]); + return res; + } + + /** + * Resolve all streams with a specific value for a given property. + * If the goal is to resolve a specific stream, this method is preferred over resolving all streams and then selecting the desired one. + * @param prop The stream_info property that should have a specific value (e.g., "name", "type", "source_id", or "desc/manufaturer"). + * @param value The string value that the property should have (e.g., "EEG" as the type property). + * @param minimum Optionally return at least this number of streams. + * @param timeout Optionally a timeout of the operation, in seconds (default: no timeout). + * If the timeout expires, less than the desired number of streams (possibly none) will be returned. + * @return An array of matching stream info objects (excluding their meta-data), any of + * which can subsequently be used to open an inlet. + */ + public static StreamInfo[] resolve_stream(string prop, string value) { return resolve_stream(prop, value, 1, FOREVER); } + public static StreamInfo[] resolve_stream(string prop, string value, int minimum) { return resolve_stream(prop, value, minimum, FOREVER); } + public static StreamInfo[] resolve_stream(string prop, string value, int minimum, double timeout) + { + IntPtr[] buf = new IntPtr[1024]; int num = dll.lsl_resolve_byprop(buf, (uint)buf.Length, prop, value, minimum, timeout); + StreamInfo[] res = new StreamInfo[num]; + for (int k = 0; k < num; k++) + res[k] = new StreamInfo(buf[k]); + return res; + } + + /** + * Resolve all streams that match a given predicate. + * Advanced query that allows to impose more conditions on the retrieved streams; the given string is an XPath 1.0 + * predicate for the <info> node (omitting the surrounding []'s), see also http://en.wikipedia.org/w/index.php?title=XPath_1.0&oldid=474981951. + * @param pred The predicate string, e.g. "name='BioSemi'" or "type='EEG' and starts-with(name,'BioSemi') and count(info/desc/channel)=32" + * @param minimum Return at least this number of streams. + * @param timeout Optionally a timeout of the operation, in seconds (default: no timeout). + * If the timeout expires, less than the desired number of streams (possibly none) will be returned. + * @return An array of matching stream info objects (excluding their meta-data), any of + * which can subsequently be used to open an inlet. + */ + public static StreamInfo[] resolve_stream(string pred) { return resolve_stream(pred, 1, FOREVER); } + public static StreamInfo[] resolve_stream(string pred, int minimum) { return resolve_stream(pred, minimum, FOREVER); } + public static StreamInfo[] resolve_stream(string pred, int minimum, double timeout) + { + IntPtr[] buf = new IntPtr[1024]; int num = dll.lsl_resolve_bypred(buf, (uint)buf.Length, pred, minimum, timeout); + StreamInfo[] res = new StreamInfo[num]; + for (int k = 0; k < num; k++) + res[k] = new StreamInfo(buf[k]); + return res; + } + + + // ====================== + // ==== Stream Inlet ==== + // ====================== + + /** + * A stream inlet. + * Inlets are used to receive streaming data (and meta-data) from the lab network. + */ + public class StreamInlet + { +/** + * Construct a new stream inlet from a resolved stream info. + * @param info A resolved stream info object (as coming from one of the resolver functions). + * Note: the stream_inlet may also be constructed with a fully-specified stream_info, + * if the desired channel format and count is already known up-front, but this is + * strongly discouraged and should only ever be done if there is no time to resolve the + * stream up-front (e.g., due to limitations in the client program). + * @param max_buflen Optionally the maximum amount of data to buffer (in seconds if there is a nominal + * sampling rate, otherwise x100 in samples). Recording applications want to use a fairly + * large buffer size here, while real-time applications would only buffer as much as + * they need to perform their next calculation. + * @param max_chunklen Optionally the maximum size, in samples, at which chunks are transmitted + * (the default corresponds to the chunk sizes used by the sender). + * Recording applications can use a generous size here (leaving it to the network how + * to pack things), while real-time applications may want a finer (perhaps 1-sample) granularity. + If left unspecified (=0), the sender determines the chunk granularity. + * @param recover Try to silently recover lost streams that are recoverable (=those that that have a source_id set). + * In all other cases (recover is false or the stream is not recoverable) functions may throw a + * LostException if the stream's source is lost (e.g., due to an app or computer crash). + */ + public StreamInlet(StreamInfo info) { obj = dll.lsl_create_inlet(info.handle(), 360, 0, 1); } + public StreamInlet(StreamInfo info, int max_buflen) { obj = dll.lsl_create_inlet(info.handle(), max_buflen, 0, 1); } + public StreamInlet(StreamInfo info, int max_buflen, int max_chunklen) { obj = dll.lsl_create_inlet(info.handle(), max_buflen, max_chunklen, 1); } + public StreamInlet(StreamInfo info, int max_buflen, int max_chunklen, bool recover) { obj = dll.lsl_create_inlet(info.handle(), max_buflen, max_chunklen, recover?1:0); } + + /** + * Destructor. + * The inlet will automatically disconnect if destroyed. + */ + ~StreamInlet() { dll.lsl_destroy_inlet(obj); } + + /** + * Retrieve the complete information of the given stream, including the extended description. + * Can be invoked at any time of the stream's lifetime. + * @param timeout Timeout of the operation (default: no timeout). + * @throws TimeoutException (if the timeout expires), or LostException (if the stream source has been lost). + */ + public StreamInfo info() { return info(FOREVER); } + public StreamInfo info(double timeout) { int ec=0; IntPtr res = dll.lsl_get_fullinfo(obj, timeout, ref ec); check_error(ec); return new StreamInfo(res); } + + /** + * Subscribe to the data stream. + * All samples pushed in at the other end from this moment onwards will be queued and + * eventually be delivered in response to pull_sample() or pull_chunk() calls. + * Pulling a sample without some preceding open_stream is permitted (the stream will then be opened implicitly). + * @param timeout Optional timeout of the operation (default: no timeout). + * @throws TimeoutException (if the timeout expires), or LostException (if the stream source has been lost). + */ + public void open_stream() { open_stream(FOREVER); } + public void open_stream(double timeout) { int ec = 0; dll.lsl_open_stream(obj, timeout, ref ec); check_error(ec); } + + /** + * Set post-processing flags to use. By default, the inlet performs NO post-processing and returns the + * ground-truth time stamps, which can then be manually synchronized using time_correction(), and then + * smoothed/dejittered if desired. This function allows automating these two and possibly more operations. + * Warning: when you enable this, you will no longer receive or be able to recover the original time stamps. + * @param flags An integer that is the result of bitwise OR'ing one or more options from processing_options_t + * together (e.g., post_clocksync|post_dejitter); the default is to enable all options. + */ + public void set_postprocessing() { set_postprocessing(processing_options_t.post_ALL); } + public void set_postprocessing(processing_options_t post_flags) { dll.lsl_set_postprocessing(obj, post_flags); } + + /** + * Drop the current data stream. + * All samples that are still buffered or in flight will be dropped and transmission + * and buffering of data for this inlet will be stopped. If an application stops being + * interested in data from a source (temporarily or not) but keeps the outlet alive, + * it should call close_stream() to not waste unnecessary system and network + * resources. + */ + public void close_stream() { dll.lsl_close_stream(obj); } + + /** + * Retrieve an estimated time correction offset for the given stream. + * The first call to this function takes several miliseconds until a reliable first estimate is obtained. + * Subsequent calls are instantaneous (and rely on periodic background updates). + * The precision of these estimates should be below 1 ms (empirically within +/-0.2 ms). + * @timeout Timeout to acquire the first time-correction estimate (default: no timeout). + * @return The time correction estimate. This is the number that needs to be added to a time stamp + * that was remotely generated via lsl_local_clock() to map it into the local clock domain of this machine. + * @throws TimeoutException (if the timeout expires), or LostException (if the stream source has been lost). + */ + public double time_correction() { return time_correction(FOREVER); } + public double time_correction(double timeout) { int ec = 0; double res = dll.lsl_time_correction(obj, timeout, ref ec); check_error(ec); return res; } + + // ======================================= + // === Pulling a sample from the inlet === + // ======================================= + + /** + * Pull a sample from the inlet and read it into an array of values. + * Handles type checking & conversion. + * @param sample An array to hold the resulting values. + * @param timeout The timeout for this operation, if any. Use 0.0 to make the function non-blocking. + * @return The capture time of the sample on the remote machine, or 0.0 if no new sample was available. + * To remap this time stamp to the local clock, add the value returned by .time_correction() to it. + * @throws LostException (if the stream source has been lost). + */ + public double pull_sample(float[] sample) { return pull_sample(sample, FOREVER); } + public double pull_sample(float[] sample, double timeout) { int ec = 0; double res = dll.lsl_pull_sample_f(obj, sample, sample.Length, timeout, ref ec); check_error(ec); return res; } + public double pull_sample(double[] sample) { return pull_sample(sample, FOREVER); } + public double pull_sample(double[] sample, double timeout) { int ec = 0; double res = dll.lsl_pull_sample_d(obj, sample, sample.Length, timeout, ref ec); check_error(ec); return res; } + public double pull_sample(int[] sample) { return pull_sample(sample, FOREVER); } + public double pull_sample(int[] sample, double timeout) { int ec = 0; double res = dll.lsl_pull_sample_i(obj, sample, sample.Length, timeout, ref ec); check_error(ec); return res; } + public double pull_sample(short[] sample) { return pull_sample(sample, FOREVER); } + public double pull_sample(short[] sample, double timeout) { int ec = 0; double res = dll.lsl_pull_sample_s(obj, sample, sample.Length, timeout, ref ec); check_error(ec); return res; } + public double pull_sample(char[] sample) { return pull_sample(sample, FOREVER); } + public double pull_sample(char[] sample, double timeout) { int ec = 0; double res = dll.lsl_pull_sample_c(obj, sample, sample.Length, timeout, ref ec); check_error(ec); return res; } + public double pull_sample(string[] sample) { return pull_sample(sample, FOREVER); } + public double pull_sample(string[] sample, double timeout) { + int ec = 0; + IntPtr[] tmp = new IntPtr[sample.Length]; + double res = dll.lsl_pull_sample_str(obj, tmp, tmp.Length, timeout, ref ec); check_error(ec); + try { + for (int k = 0; k < tmp.Length; k++) + sample[k] = Marshal.PtrToStringAnsi(tmp[k]); + } finally { + for (int k = 0; k < tmp.Length; k++) + dll.lsl_destroy_string(tmp[k]); + } + return res; + } + + + // ================================================= + // === Pulling a chunk of samples from the inlet === + // ================================================= + + /** + * Pull a chunk of data from the inlet. + * @param data_buffer A pre-allocated buffer where the channel data shall be stored. + * @param timestamp_buffer A pre-allocated buffer where time stamps shall be stored. + * @param timeout Optionally the timeout for this operation, if any. When the timeout expires, the function + * may return before the entire buffer is filled. The default value of 0.0 will retrieve only + * data available for immediate pickup. + * @return samples_written Number of samples written to the data and timestamp buffers. + * @throws LostException (if the stream source has been lost). + */ + public int pull_chunk(float[,] data_buffer, double[] timestamp_buffer) { return pull_chunk(data_buffer, timestamp_buffer, 0.0); } + public int pull_chunk(float[,] data_buffer, double[] timestamp_buffer, double timeout) { int ec = 0; uint res = dll.lsl_pull_chunk_f(obj, data_buffer, timestamp_buffer, (uint)data_buffer.Length, (uint)timestamp_buffer.Length, timeout, ref ec); check_error(ec); return (int)res / data_buffer.GetLength(1); } + public int pull_chunk(double[,] data_buffer, double[] timestamp_buffer) { return pull_chunk(data_buffer, timestamp_buffer, 0.0); } + public int pull_chunk(double[,] data_buffer, double[] timestamp_buffer, double timeout) { int ec = 0; uint res = dll.lsl_pull_chunk_d(obj, data_buffer, timestamp_buffer, (uint)data_buffer.Length, (uint)timestamp_buffer.Length, timeout, ref ec); check_error(ec); return (int)res / data_buffer.GetLength(1); } + public int pull_chunk(int[,] data_buffer, double[] timestamp_buffer) { return pull_chunk(data_buffer, timestamp_buffer, 0.0); } + public int pull_chunk(int[,] data_buffer, double[] timestamp_buffer, double timeout) { int ec = 0; uint res = dll.lsl_pull_chunk_i(obj, data_buffer, timestamp_buffer, (uint)data_buffer.Length, (uint)timestamp_buffer.Length, timeout, ref ec); check_error(ec); return (int)res / data_buffer.GetLength(1); } + public int pull_chunk(short[,] data_buffer, double[] timestamp_buffer) { return pull_chunk(data_buffer, timestamp_buffer, 0.0); } + public int pull_chunk(short[,] data_buffer, double[] timestamp_buffer, double timeout) { int ec = 0; uint res = dll.lsl_pull_chunk_s(obj, data_buffer, timestamp_buffer, (uint)data_buffer.Length, (uint)timestamp_buffer.Length, timeout, ref ec); check_error(ec); return (int)res / data_buffer.GetLength(1); } + public int pull_chunk(char[,] data_buffer, double[] timestamp_buffer) { return pull_chunk(data_buffer, timestamp_buffer, 0.0); } + public int pull_chunk(char[,] data_buffer, double[] timestamp_buffer, double timeout) { int ec = 0; uint res = dll.lsl_pull_chunk_c(obj, data_buffer, timestamp_buffer, (uint)data_buffer.Length, (uint)timestamp_buffer.Length, timeout, ref ec); check_error(ec); return (int)res / data_buffer.GetLength(1); } + public int pull_chunk(string[,] data_buffer, double[] timestamp_buffer) { return pull_chunk(data_buffer, timestamp_buffer, 0.0); } + public int pull_chunk(string[,] data_buffer, double[] timestamp_buffer, double timeout) { + int ec = 0; + IntPtr[,] tmp = new IntPtr[data_buffer.GetLength(0),data_buffer.GetLength(1)]; + uint res = dll.lsl_pull_chunk_str(obj, tmp, timestamp_buffer, (uint)tmp.Length, (uint)timestamp_buffer.Length, timeout, ref ec); + check_error(ec); + try { + for (int s = 0; s < tmp.GetLength(0); s++) + for (int c = 0; c < tmp.GetLength(1); c++) + data_buffer[s,c] = Marshal.PtrToStringAnsi(tmp[s,c]); + } finally { + for (int s = 0; s < tmp.GetLength(0); s++) + for (int c = 0; c < tmp.GetLength(1); c++) + dll.lsl_destroy_string(tmp[s,c]); + } + return (int)res / data_buffer.GetLength(1); + } + + /** + * Query whether samples are currently available for immediate pickup. + * Note that it is not a good idea to use samples_available() to determine whether + * a pull_*() call would block: to be sure, set the pull timeout to 0.0 or an acceptably + * low value. If the underlying implementation supports it, the value will be the number of + * samples available (otherwise it will be 1 or 0). + */ + public int samples_available() { return (int)dll.lsl_samples_available(obj); } + + /** + * Query whether the clock was potentially reset since the last call to was_clock_reset(). + * This is a rarely-used function that is only useful to applications that combine multiple time_correction + * values to estimate precise clock drift; it allows to tolerate cases where the source machine was + * hot-swapped or restarted in between two measurements. + */ + public bool was_clock_reset() { return (int)dll.lsl_was_clock_reset(obj)!=0; } + + private IntPtr obj; + } + + + // ===================== + // ==== XML Element ==== + // ===================== + + /** + * A lightweight XML element tree; models the .desc() field of stream_info. + * Has a name and can have multiple named children or have text content as value; attributes are omitted. + * Insider note: The interface is modeled after a subset of pugixml's node type and is compatible with it. + * See also http://pugixml.googlecode.com/svn/tags/latest/docs/manual/access.html for additional documentation. + */ + public struct XMLElement { + public XMLElement(IntPtr handle) { obj = handle; } + + // === Tree Navigation === + + /// Get the first child of the element. + public XMLElement first_child() { return new XMLElement(dll.lsl_first_child(obj)); } + + /// Get the last child of the element. + public XMLElement last_child() { return new XMLElement(dll.lsl_last_child(obj)); } + + /// Get the next sibling in the children list of the parent node. + public XMLElement next_sibling() { return new XMLElement(dll.lsl_next_sibling(obj)); } + + /// Get the previous sibling in the children list of the parent node. + public XMLElement previous_sibling() { return new XMLElement(dll.lsl_previous_sibling(obj)); } + + /// Get the parent node. + public XMLElement parent() { return new XMLElement(dll.lsl_parent(obj)); } + + + // === Tree Navigation by Name === + + /// Get a child with a specified name. + public XMLElement child(string name) { return new XMLElement(dll.lsl_child(obj,name)); } + + /// Get the next sibling with the specified name. + public XMLElement next_sibling(string name) { return new XMLElement(dll.lsl_next_sibling_n(obj, name)); } + + /// Get the previous sibling with the specified name. + public XMLElement previous_sibling(string name) { return new XMLElement(dll.lsl_previous_sibling_n(obj, name)); } + + + // === Content Queries === + + /// Whether this node is empty. + public bool empty() { return dll.lsl_empty(obj)!=0; } + + /// Whether this is a text body (instead of an XML element). True both for plain char data and CData. + public bool is_text() { return dll.lsl_is_text(obj) != 0; } + + /// Name of the element. + public string name() { return Marshal.PtrToStringAnsi(dll.lsl_name(obj)); } + + /// Value of the element. + public string value() { return Marshal.PtrToStringAnsi(dll.lsl_value(obj)); } + + /// Get child value (value of the first child that is text). + public string child_value() { return Marshal.PtrToStringAnsi(dll.lsl_child_value(obj)); } + + /// Get child value of a child with a specified name. + public string child_value(string name) { return Marshal.PtrToStringAnsi(dll.lsl_child_value_n(obj,name)); } + + + // === Modification === + + /** + * Append a child node with a given name, which has a (nameless) plain-text child with the given text value. + */ + public XMLElement append_child_value(string name, string value) { return new XMLElement(dll.lsl_append_child_value(obj, name, value)); } + + /** + * Prepend a child node with a given name, which has a (nameless) plain-text child with the given text value. + */ + public XMLElement prepend_child_value(string name, string value) { return new XMLElement(dll.lsl_prepend_child_value(obj, name, value)); } + + /** + * Set the text value of the (nameless) plain-text child of a named child node. + */ + public bool set_child_value(string name, string value) { return dll.lsl_set_child_value(obj, name, value) != 0; } + + /** + * Set the element's name. + * @return False if the node is empty. + */ + public bool set_name(string rhs) { return dll.lsl_set_name(obj, rhs) != 0; } + + /** + * Set the element's value. + * @return False if the node is empty. + */ + public bool set_value(string rhs) { return dll.lsl_set_value(obj, rhs) != 0; } + + /// Append a child element with the specified name. + public XMLElement append_child(string name) { return new XMLElement(dll.lsl_append_child(obj, name)); } + + /// Prepend a child element with the specified name. + public XMLElement prepend_child(string name) { return new XMLElement(dll.lsl_prepend_child(obj, name)); } + + /// Append a copy of the specified element as a child. + public XMLElement append_copy(XMLElement e) { return new XMLElement(dll.lsl_append_copy(obj, e.obj)); } + + /// Prepend a child element with the specified name. + public XMLElement prepend_copy(XMLElement e) { return new XMLElement(dll.lsl_prepend_copy(obj, e.obj)); } + + /// Remove a child element with the specified name. + public void remove_child(string name) { dll.lsl_remove_child_n(obj, name); } + + /// Remove a specified child element. + public void remove_child(XMLElement e) { dll.lsl_remove_child(obj, e.obj); } + + IntPtr obj; + } + + + // =========================== + // === Continuous Resolver === + // =========================== + + /** + * A convenience class that resolves streams continuously in the background throughout + * its lifetime and which can be queried at any time for the set of streams that are currently + * visible on the network. + */ + + public class ContinuousResolver + { + /** + * Construct a new continuous_resolver that resolves all streams on the network. + * This is analogous to the functionality offered by the free function resolve_streams(). + * @param forget_after When a stream is no longer visible on the network (e.g., because it was shut down), + * this is the time in seconds after which it is no longer reported by the resolver. + */ + public ContinuousResolver() { obj = dll.lsl_create_continuous_resolver(5.0); } + public ContinuousResolver(double forget_after) { obj = dll.lsl_create_continuous_resolver(forget_after); } + + /** + * Construct a new continuous_resolver that resolves all streams with a specific value for a given property. + * This is analogous to the functionality provided by the free function resolve_stream(prop,value). + * @param prop The stream_info property that should have a specific value (e.g., "name", "type", "source_id", or "desc/manufaturer"). + * @param value The string value that the property should have (e.g., "EEG" as the type property). + * @param forget_after When a stream is no longer visible on the network (e.g., because it was shut down), + * this is the time in seconds after which it is no longer reported by the resolver. + */ + public ContinuousResolver(string prop, string value) { obj = dll.lsl_create_continuous_resolver_byprop(prop, value, 5.0); } + public ContinuousResolver(string prop, string value, double forget_after) { obj = dll.lsl_create_continuous_resolver_byprop(prop, value, forget_after); } + + /** + * Construct a new continuous_resolver that resolves all streams that match a given XPath 1.0 predicate. + * This is analogous to the functionality provided by the free function resolve_stream(pred). + * @param pred The predicate string, e.g. "name='BioSemi'" or "type='EEG' and starts-with(name,'BioSemi') and count(info/desc/channel)=32" + * @param forget_after When a stream is no longer visible on the network (e.g., because it was shut down), + * this is the time in seconds after which it is no longer reported by the resolver. + */ + public ContinuousResolver(string pred) { obj = dll.lsl_create_continuous_resolver_bypred(pred, 5.0); } + public ContinuousResolver(string pred, double forget_after) { obj = dll.lsl_create_continuous_resolver_bypred(pred, forget_after); } + + /** + * Destructor. + */ + ~ContinuousResolver() { dll.lsl_destroy_continuous_resolver(obj); } + + /** + * Obtain the set of currently present streams on the network (i.e. resolve result). + * @return An array of matching stream info objects (excluding their meta-data), any of + * which can subsequently be used to open an inlet. + */ + public StreamInfo[] results() + { + IntPtr[] buf = new IntPtr[1024]; + int num = dll.lsl_resolver_results(obj,buf,(uint)buf.Length); + StreamInfo[] res = new StreamInfo[num]; + for (int k = 0; k < num; k++) + res[k] = new StreamInfo(buf[k]); + return res; + } + + private IntPtr obj; + } + + // ======================= + // === Exception Types === + // ======================= + + /** + * Exception class that indicates that a stream inlet's source has been irrecoverably lost. + */ + public class LostException : System.Exception + { + public LostException() { } + public LostException(string message) { } + public LostException(string message, System.Exception inner) { } + protected LostException(System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) { } + } + + /** + * Exception class that indicates that an internal error has occurred inside liblsl. + */ + public class InternalException : System.Exception + { + public InternalException() { } + public InternalException(string message) { } + public InternalException(string message, System.Exception inner) { } + protected InternalException(System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) { } + } + + /** + * Check an error condition and throw an exception if appropriate. + */ + public static void check_error(int ec) { + if (ec < 0) + switch (ec) { + case -1: throw new TimeoutException("The operation failed due to a timeout."); + case -2: throw new LostException("The stream has been lost."); + case -3: throw new ArgumentException("An argument was incorrectly specified (e.g., wrong format or wrong length)."); + case -4: throw new InternalException("An internal internal error has occurred."); + default: throw new Exception("An unknown error has occurred."); + } + } + + + + // === Internal: C library function definitions. === + + class dll { - /** - * Constant to indicate that a stream has variable sampling rate. - */ - public const double IRREGULAR_RATE = 0.0; - - /** - * Constant to indicate that a sample has the next successive time stamp. - * This is an optional optimization to transmit less data per sample. - * The stamp is then deduced from the preceding one according to the stream's sampling rate - * (in the case of an irregular rate, the same time stamp as before will is assumed). - */ - public const double DEDUCED_TIMESTAMP = -1.0; - - - /** - * A very large time duration (> 1 year) for timeout values. - * Note that significantly larger numbers can cause the timeout to be invalid on some operating systems (e.g., 32-bit UNIX). - */ - public const double FOREVER = 32000000.0; - - /** - * Data format of a channel (each transmitted sample holds an array of channels). - */ - public enum channel_format_t : byte - { - cf_float32 = 1, // For up to 24-bit precision measurements in the appropriate physical unit - // (e.g., microvolts). Integers from -16777216 to 16777216 are represented accurately. - cf_double64 = 2, // For universal numeric data as long as permitted by network & disk budget. - // The largest representable integer is 53-bit. - cf_string = 3, // For variable-length ASCII strings or data blobs, such as video frames, - // complex event descriptions, etc. - cf_int32 = 4, // For high-rate digitized formats that require 32-bit precision. Depends critically on - // meta-data to represent meaningful units. Useful for application event codes or other coded data. - cf_int16 = 5, // For very high rate signals (40Khz+) or consumer-grade audio - // (for professional audio float is recommended). - cf_int8 = 6, // For binary signals or other coded data. - // Not recommended for encoding string data. - cf_int64 = 7, // For now only for future compatibility. Support for this type is not yet exposed in all languages. - // Also, some builds of liblsl will not be able to send or receive data of this type. - cf_undefined = 0 // Can not be transmitted. - }; - - /** - * Protocol version. - * The major version is protocol_version() / 100; - * The minor version is protocol_version() % 100; - * Clients with different minor versions are protocol-compatible with each other - * while clients with different major versions will refuse to work together. - */ - public static int protocol_version() { return dll.lsl_protocol_version(); } - - /** - * Version of the liblsl library. - * The major version is library_version() / 100; - * The minor version is library_version() % 100; - */ - public static int library_version() { return dll.lsl_library_version(); } - - /** - * Obtain a local system time stamp in seconds. The resolution is better than a millisecond. - * This reading can be used to assign time stamps to samples as they are being acquired. - * If the "age" of a sample is known at a particular time (e.g., from USB transmission - * delays), it can be used as an offset to local_clock() to obtain a better estimate of - * when a sample was actually captured. See stream_outlet::push_sample() for a use case. - */ - public static double local_clock() { return dll.lsl_local_clock(); } - - - - - // ========================== - // === Stream Declaration === - // ========================== - - /** - * The stream_info object stores the declaration of a data stream. - * Represents the following information: - * a) stream data format (#channels, channel format) - * b) core information (stream name, content type, sampling rate) - * c) optional meta-data about the stream content (channel labels, measurement units, etc.) - * - * Whenever a program wants to provide a new stream on the lab network it will typically first - * create a stream_info to describe its properties and then construct a stream_outlet with it to create - * the stream on the network. Recipients who discover the outlet can query the stream_info; it is also - * written to disk when recording the stream (playing a similar role as a file header). - */ - - public class StreamInfo - { - /** - * Construct a new StreamInfo object. - * Core stream information is specified here. Any remaining meta-data can be added later. - * @param name Name of the stream. Describes the device (or product series) that this stream makes available - * (for use by programs, experimenters or data analysts). Cannot be empty. - * @param type Content type of the stream. Please see Table of Content Types in the documentation for naming recommendations. - * The content type is the preferred way to find streams (as opposed to searching by name). - * @param channel_count Number of channels per sample. This stays constant for the lifetime of the stream. - * @param nominal_srate The sampling rate (in Hz) as advertised by the data source, if regular (otherwise set to IRREGULAR_RATE). - * @param channel_format Format/type of each channel. If your channels have different formats, consider supplying - * multiple streams or use the largest type that can hold them all (such as cf_double64). - * @param source_id Unique identifier of the device or source of the data, if available (such as the serial number). - * This is critical for system robustness since it allows recipients to recover from failure even after the - * serving app, device or computer crashes (just by finding a stream with the same source id on the network again). - * Therefore, it is highly recommended to always try to provide whatever information can uniquely identify the data source itself. - */ - public StreamInfo(string name, string type) { obj = dll.lsl_create_streaminfo(name, type, 1, IRREGULAR_RATE, channel_format_t.cf_float32, ""); } - public StreamInfo(string name, string type, int channel_count) { obj = dll.lsl_create_streaminfo(name, type, channel_count, IRREGULAR_RATE, channel_format_t.cf_float32, ""); } - public StreamInfo(string name, string type, int channel_count, double nominal_srate) { obj = dll.lsl_create_streaminfo(name, type, channel_count, nominal_srate, channel_format_t.cf_float32, ""); } - public StreamInfo(string name, string type, int channel_count, double nominal_srate, channel_format_t channel_format) { obj = dll.lsl_create_streaminfo(name, type, channel_count, nominal_srate, channel_format, ""); } - public StreamInfo(string name, string type, int channel_count, double nominal_srate, channel_format_t channel_format, string source_id) { obj = dll.lsl_create_streaminfo(name, type, channel_count, nominal_srate, channel_format, source_id); } - public StreamInfo(IntPtr handle) { obj = handle; } - - /// Destroy a previously created streaminfo object. - ~StreamInfo() { dll.lsl_destroy_streaminfo(obj); } - - // ======================== - // === Core Information === - // ======================== - // (these fields are assigned at construction) - - /** - * Name of the stream. - * This is a human-readable name. For streams offered by device modules, it refers to the type of device or product series - * that is generating the data of the stream. If the source is an application, the name may be a more generic or specific identifier. - * Multiple streams with the same name can coexist, though potentially at the cost of ambiguity (for the recording app or experimenter). - */ - public string name() { return Marshal.PtrToStringAnsi(dll.lsl_get_name(obj)); } - - - /** - * Content type of the stream. - * The content type is a short string such as "EEG", "Gaze" which describes the content carried by the channel (if known). - * If a stream contains mixed content this value need not be assigned but may instead be stored in the description of channel types. - * To be useful to applications and automated processing systems using the recommended content types is preferred. - * See Table of Content Types in the documentation. - */ - public String type() { return Marshal.PtrToStringAnsi(dll.lsl_get_type(obj)); } - - /** - * Number of channels of the stream. - * A stream has at least one channel; the channel count stays constant for all samples. - */ - public int channel_count() { return dll.lsl_get_channel_count(obj); } - - /** - * Sampling rate of the stream, according to the source (in Hz). - * If a stream is irregularly sampled, this should be set to IRREGULAR_RATE. - * - * Note that no data will be lost even if this sampling rate is incorrect or if a device has temporary - * hiccups, since all samples will be recorded anyway (except for those dropped by the device itself). However, - * when the recording is imported into an application, a good importer may correct such errors more accurately - * if the advertised sampling rate was close to the specs of the device. - */ - public double nominal_srate() { return dll.lsl_get_nominal_srate(obj); } - - /** - * Channel format of the stream. - * All channels in a stream have the same format. However, a device might offer multiple time-synched streams - * each with its own format. - */ - public channel_format_t channel_format() { return dll.lsl_get_channel_format(obj); } - - /** - * Unique identifier of the stream's source, if available. - * The unique source (or device) identifier is an optional piece of information that, if available, allows that - * endpoints (such as the recording program) can re-acquire a stream automatically once it is back online. - */ - public string source_id() { return Marshal.PtrToStringAnsi(dll.lsl_get_source_id(obj)); } - - - // ====================================== - // === Additional Hosting Information === - // ====================================== - // (these fields are implicitly assigned once bound to an outlet/inlet) - - /** - * Protocol version used to deliver the stream. - */ - public int version() { return dll.lsl_get_version(obj); } - - /** - * Creation time stamp of the stream. - * This is the time stamp when the stream was first created - * (as determined via local_clock() on the providing machine). - */ - public double created_at() { return dll.lsl_get_created_at(obj); } - - /** - * Unique ID of the stream outlet instance (once assigned). - * This is a unique identifier of the stream outlet, and is guaranteed to be different - * across multiple instantiations of the same outlet (e.g., after a re-start). - */ - public string uid() { return Marshal.PtrToStringAnsi(dll.lsl_get_uid(obj)); } - - /** - * Session ID for the given stream. - * The session id is an optional human-assigned identifier of the recording session. - * While it is rarely used, it can be used to prevent concurrent recording activitites - * on the same sub-network (e.g., in multiple experiment areas) from seeing each other's streams - * (assigned via a configuration file by the experimenter, see Configuration File in the docs). - */ - public string session_id() { return Marshal.PtrToStringAnsi(dll.lsl_get_session_id(obj)); } - - /** - * Hostname of the providing machine. - */ - public string hostname() { return Marshal.PtrToStringAnsi(dll.lsl_get_hostname(obj)); } - - - // ======================== - // === Data Description === - // ======================== - - /** - * Extended description of the stream. - * It is highly recommended that at least the channel labels are described here. - * See code examples in the documentation. Other information, such as amplifier settings, - * measurement units if deviating from defaults, setup information, subject information, etc., - * can be specified here, as well. See Meta-Data Recommendations in the docs. - * - * Important: if you use a stream content type for which meta-data recommendations exist, please - * try to lay out your meta-data in agreement with these recommendations for compatibility with other applications. - */ - public XMLElement desc() { return new XMLElement(dll.lsl_get_desc(obj)); } - - /** - * Retrieve the entire stream_info in XML format. - * This yields an XML document (in string form) whose top-level element is <info>. The info element contains - * one element for each field of the stream_info class, including: - * a) the core elements <name>, <type>, <channel_count>, <nominal_srate>, <channel_format>, <source_id> - * b) the misc elements <version>, <created_at>, <uid>, <session_id>, <v4address>, <v4data_port>, <v4service_port>, <v6address>, <v6data_port>, <v6service_port> - * c) the extended description element <desc> with user-defined sub-elements. - */ - public string as_xml() - { - IntPtr pXml = dll.lsl_get_xml(obj); - string strXml = Marshal.PtrToStringAnsi(pXml); - dll.lsl_destroy_string(pXml); - return strXml; - } - - - /** - * Get access to the underlying handle. - */ - public IntPtr handle() { return obj; } - - private IntPtr obj; - } - - - // ======================= - // ==== Stream Outlet ==== - // ======================= - - /** - * A stream outlet. - * Outlets are used to make streaming data (and the meta-data) available on the lab network. - */ - public class StreamOutlet - { - /** - * Establish a new stream outlet. This makes the stream discoverable. - * @param info The stream information to use for creating this stream. Stays constant over the lifetime of the outlet. - * @param chunk_size Optionally the desired chunk granularity (in samples) for transmission. If unspecified, - * each push operation yields one chunk. Inlets can override this setting. - * @param max_buffered Optionally the maximum amount of data to buffer (in seconds if there is a nominal - * sampling rate, otherwise x100 in samples). The default is 6 minutes of data. - */ - public StreamOutlet(StreamInfo info) { obj = dll.lsl_create_outlet(info.handle(), 0, 360); } - public StreamOutlet(StreamInfo info, int chunk_size) { obj = dll.lsl_create_outlet(info.handle(), chunk_size, 360); } - public StreamOutlet(StreamInfo info, int chunk_size, int max_buffered) { obj = dll.lsl_create_outlet(info.handle(), chunk_size, max_buffered); } - - /** - * Destructor. - * The stream will no longer be discoverable after destruction and all paired inlets will stop delivering data. - */ - ~StreamOutlet() { dll.lsl_destroy_outlet(obj); } - - - // ======================================== - // === Pushing a sample into the outlet === - // ======================================== - - /** - * Push an array of values as a sample into the outlet. - * Each entry in the vector corresponds to one channel. - * @param data An array of values to push (one for each channel). - * @param timestamp Optionally the capture time of the sample, in agreement with local_clock(); if omitted, the current time is used. - * @param pushthrough Optionally whether to push the sample through to the receivers instead of buffering it with subsequent samples. - * Note that the chunk_size, if specified at outlet construction, takes precedence over the pushthrough flag. - */ - public void push_sample(float[] data) { dll.lsl_push_sample_ftp(obj, data, 0.0, 1); } - public void push_sample(float[] data, double timestamp) { dll.lsl_push_sample_ftp(obj, data, timestamp, 1); } - public void push_sample(float[] data, double timestamp, bool pushthrough) { dll.lsl_push_sample_ftp(obj, data, timestamp, pushthrough ? 1 : 0); } - public void push_sample(double[] data) { dll.lsl_push_sample_dtp(obj, data, 0.0, 1); } - public void push_sample(double[] data, double timestamp) { dll.lsl_push_sample_dtp(obj, data, timestamp, 1); } - public void push_sample(double[] data, double timestamp, bool pushthrough) { dll.lsl_push_sample_dtp(obj, data, timestamp, pushthrough ? 1 : 0); } - public void push_sample(int[] data) { dll.lsl_push_sample_itp(obj, data, 0.0, 1); } - public void push_sample(int[] data, double timestamp) { dll.lsl_push_sample_itp(obj, data, timestamp, 1); } - public void push_sample(int[] data, double timestamp, bool pushthrough) { dll.lsl_push_sample_itp(obj, data, timestamp, pushthrough ? 1 : 0); } - public void push_sample(short[] data) { dll.lsl_push_sample_stp(obj, data, 0.0, 1); } - public void push_sample(short[] data, double timestamp) { dll.lsl_push_sample_stp(obj, data, timestamp, 1); } - public void push_sample(short[] data, double timestamp, bool pushthrough) { dll.lsl_push_sample_stp(obj, data, timestamp, pushthrough ? 1 : 0); } - public void push_sample(char[] data) { dll.lsl_push_sample_ctp(obj, data, 0.0, 1); } - public void push_sample(char[] data, double timestamp) { dll.lsl_push_sample_ctp(obj, data, timestamp, 1); } - public void push_sample(char[] data, double timestamp, bool pushthrough) { dll.lsl_push_sample_ctp(obj, data, timestamp, pushthrough ? 1 : 0); } - public void push_sample(string[] data) { dll.lsl_push_sample_strtp(obj, data, 0.0, 1); } - public void push_sample(string[] data, double timestamp) { dll.lsl_push_sample_strtp(obj, data, timestamp, 1); } - public void push_sample(string[] data, double timestamp, bool pushthrough) { dll.lsl_push_sample_strtp(obj, data, timestamp, pushthrough ? 1 : 0); } - - - // =================================================== - // === Pushing an chunk of samples into the outlet === - // =================================================== - - /** - * Push a chunk of samples into the outlet. Single timestamp provided. - * @param data A rectangular array of values for multiple samples. - * @param timestamp Optionally the capture time of the most recent sample, in agreement with local_clock(); if omitted, the current time is used. - * The time stamps of other samples are automatically derived based on the sampling rate of the stream. - * @param pushthrough Optionally whether to push the chunk through to the receivers instead of buffering it with subsequent samples. - * Note that the chunk_size, if specified at outlet construction, takes precedence over the pushthrough flag. - */ - public void push_chunk(float[,] data) { dll.lsl_push_chunk_ftp(obj, data, (uint)data.Length, 0.0, 1); } - public void push_chunk(float[,] data, double timestamp) { dll.lsl_push_chunk_ftp(obj, data, (uint)data.Length, timestamp, 1); } - public void push_chunk(float[,] data, double timestamp, bool pushthrough) { dll.lsl_push_chunk_ftp(obj, data, (uint)data.Length, timestamp, pushthrough ? 1 : 0); } - public void push_chunk(double[,] data) { dll.lsl_push_chunk_dtp(obj, data, (uint)data.Length, 0.0, 1); } - public void push_chunk(double[,] data, double timestamp) { dll.lsl_push_chunk_dtp(obj, data, (uint)data.Length, timestamp, 1); } - public void push_chunk(double[,] data, double timestamp, bool pushthrough) { dll.lsl_push_chunk_dtp(obj, data, (uint)data.Length, timestamp, pushthrough ? 1 : 0); } - public void push_chunk(int[,] data) { dll.lsl_push_chunk_itp(obj, data, (uint)data.Length, 0.0, 1); } - public void push_chunk(int[,] data, double timestamp) { dll.lsl_push_chunk_itp(obj, data, (uint)data.Length, timestamp, 1); } - public void push_chunk(int[,] data, double timestamp, bool pushthrough) { dll.lsl_push_chunk_itp(obj, data, (uint)data.Length, timestamp, pushthrough ? 1 : 0); } - public void push_chunk(short[,] data) { dll.lsl_push_chunk_stp(obj, data, (uint)data.Length, 0.0, 1); } - public void push_chunk(short[,] data, double timestamp) { dll.lsl_push_chunk_stp(obj, data, (uint)data.Length, timestamp, 1); } - public void push_chunk(short[,] data, double timestamp, bool pushthrough) { dll.lsl_push_chunk_stp(obj, data, (uint)data.Length, timestamp, pushthrough ? 1 : 0); } - public void push_chunk(char[,] data) { dll.lsl_push_chunk_ctp(obj, data, (uint)data.Length, 0.0, 1); } - public void push_chunk(char[,] data, double timestamp) { dll.lsl_push_chunk_ctp(obj, data, (uint)data.Length, timestamp, 1); } - public void push_chunk(char[,] data, double timestamp, bool pushthrough) { dll.lsl_push_chunk_ctp(obj, data, (uint)data.Length, timestamp, pushthrough ? 1 : 0); } - public void push_chunk(string[,] data) { dll.lsl_push_chunk_strtp(obj, data, (uint)data.Length, 0.0, 1); } - public void push_chunk(string[,] data, double timestamp) { dll.lsl_push_chunk_strtp(obj, data, (uint)data.Length, timestamp, 1); } - public void push_chunk(string[,] data, double timestamp, bool pushthrough) { dll.lsl_push_chunk_strtp(obj, data, (uint)data.Length, timestamp, pushthrough ? 1 : 0); } - - /** - * Push a chunk of multiplexed samples into the outlet. One timestamp per sample is provided. - * @param data A rectangular array of values for multiple samples. - * @param timestamps An array of timestamp values holding time stamps for each sample in the data buffer. - * @param pushthrough Optionally whether to push the chunk through to the receivers instead of buffering it with subsequent samples. - * Note that the chunk_size, if specified at outlet construction, takes precedence over the pushthrough flag. - */ - public void push_chunk(float[,] data, double[] timestamps) { dll.lsl_push_chunk_ftnp(obj, data, (uint)data.Length, timestamps, 1); } - public void push_chunk(float[,] data, double[] timestamps, bool pushthrough) { dll.lsl_push_chunk_ftnp(obj, data, (uint)data.Length, timestamps, pushthrough ? 1 : 0); } - public void push_chunk(double[,] data, double[] timestamps) { dll.lsl_push_chunk_dtnp(obj, data, (uint)data.Length, timestamps, 1); } - public void push_chunk(double[,] data, double[] timestamps, bool pushthrough) { dll.lsl_push_chunk_dtnp(obj, data, (uint)data.Length, timestamps, pushthrough ? 1 : 0); } - public void push_chunk(int[,] data, double[] timestamps) { dll.lsl_push_chunk_itnp(obj, data, (uint)data.Length, timestamps, 1); } - public void push_chunk(int[,] data, double[] timestamps, bool pushthrough) { dll.lsl_push_chunk_itnp(obj, data, (uint)data.Length, timestamps, pushthrough ? 1 : 0); } - public void push_chunk(short[,] data, double[] timestamps) { dll.lsl_push_chunk_stnp(obj, data, (uint)data.Length, timestamps, 1); } - public void push_chunk(short[,] data, double[] timestamps, bool pushthrough) { dll.lsl_push_chunk_stnp(obj, data, (uint)data.Length, timestamps, pushthrough ? 1 : 0); } - public void push_chunk(char[,] data, double[] timestamps) { dll.lsl_push_chunk_ctnp(obj, data, (uint)data.Length, timestamps, 1); } - public void push_chunk(char[,] data, double[] timestamps, bool pushthrough) { dll.lsl_push_chunk_ctnp(obj, data, (uint)data.Length, timestamps, pushthrough ? 1 : 0); } - public void push_chunk(string[,] data, double[] timestamps) { dll.lsl_push_chunk_strtnp(obj, data, (uint)data.Length, timestamps, 1); } - public void push_chunk(string[,] data, double[] timestamps, bool pushthrough) { dll.lsl_push_chunk_strtnp(obj, data, (uint)data.Length, timestamps, pushthrough ? 1 : 0); } - - - // =============================== - // === Miscellaneous Functions === - // =============================== - - /** - * Check whether consumers are currently registered. - * While it does not hurt, there is technically no reason to push samples if there is no consumer. - */ - public bool have_consumers() { return dll.lsl_have_consumers(obj) > 0; } - - /** - * Wait until some consumer shows up (without wasting resources). - * @return True if the wait was successful, false if the timeout expired. - */ - public bool wait_for_consumers(double timeout) { return dll.lsl_wait_for_consumers(obj) > 0; } - - /** - * Retrieve the stream info provided by this outlet. - * This is what was used to create the stream (and also has the Additional Network Information fields assigned). - */ - public StreamInfo info() { return new StreamInfo(dll.lsl_get_info(obj)); } - - private IntPtr obj; - } - - - // =========================== - // ==== Resolve Functions ==== - // =========================== - - /** - * Resolve all streams on the network. - * This function returns all currently available streams from any outlet on the network. - * The network is usually the subnet specified at the local router, but may also include - * a multicast group of machines (given that the network supports it), or list of hostnames. - * These details may optionally be customized by the experimenter in a configuration file - * (see Network Connectivity in the LSL wiki). - * This is the default mechanism used by the browsing programs and the recording program. - * @param wait_time The waiting time for the operation, in seconds, to search for streams. - * Warning: If this is too short (less than 0.5s) only a subset (or none) of the - * outlets that are present on the network may be returned. - * @return An array of stream info objects (excluding their desc field), any of which can - * subsequently be used to open an inlet. The full info can be retrieve from the inlet. - */ - public static StreamInfo[] resolve_streams() { return resolve_streams(1.0); } - public static StreamInfo[] resolve_streams(double wait_time) - { - IntPtr[] buf = new IntPtr[1024]; int num = dll.lsl_resolve_all(buf, (uint)buf.Length, wait_time); - StreamInfo[] res = new StreamInfo[num]; - for (int k = 0; k < num; k++) - res[k] = new StreamInfo(buf[k]); - return res; - } - - /** - * Resolve all streams with a specific value for a given property. - * If the goal is to resolve a specific stream, this method is preferred over resolving all streams and then selecting the desired one. - * @param prop The stream_info property that should have a specific value (e.g., "name", "type", "source_id", or "desc/manufaturer"). - * @param value The string value that the property should have (e.g., "EEG" as the type property). - * @param minimum Optionally return at least this number of streams. - * @param timeout Optionally a timeout of the operation, in seconds (default: no timeout). - * If the timeout expires, less than the desired number of streams (possibly none) will be returned. - * @return An array of matching stream info objects (excluding their meta-data), any of - * which can subsequently be used to open an inlet. - */ - public static StreamInfo[] resolve_stream(string prop, string value) { return resolve_stream(prop, value, 1, FOREVER); } - public static StreamInfo[] resolve_stream(string prop, string value, int minimum) { return resolve_stream(prop, value, minimum, FOREVER); } - public static StreamInfo[] resolve_stream(string prop, string value, int minimum, double timeout) - { - IntPtr[] buf = new IntPtr[1024]; int num = dll.lsl_resolve_byprop(buf, (uint)buf.Length, prop, value, minimum, timeout); - StreamInfo[] res = new StreamInfo[num]; - for (int k = 0; k < num; k++) - res[k] = new StreamInfo(buf[k]); - return res; - } - - /** - * Resolve all streams that match a given predicate. - * Advanced query that allows to impose more conditions on the retrieved streams; the given string is an XPath 1.0 - * predicate for the <info> node (omitting the surrounding []'s), see also http://en.wikipedia.org/w/index.php?title=XPath_1.0&oldid=474981951. - * @param pred The predicate string, e.g. "name='BioSemi'" or "type='EEG' and starts-with(name,'BioSemi') and count(info/desc/channel)=32" - * @param minimum Return at least this number of streams. - * @param timeout Optionally a timeout of the operation, in seconds (default: no timeout). - * If the timeout expires, less than the desired number of streams (possibly none) will be returned. - * @return An array of matching stream info objects (excluding their meta-data), any of - * which can subsequently be used to open an inlet. - */ - public static StreamInfo[] resolve_stream(string pred) { return resolve_stream(pred, 1, FOREVER); } - public static StreamInfo[] resolve_stream(string pred, int minimum) { return resolve_stream(pred, minimum, FOREVER); } - public static StreamInfo[] resolve_stream(string pred, int minimum, double timeout) - { - IntPtr[] buf = new IntPtr[1024]; int num = dll.lsl_resolve_bypred(buf, (uint)buf.Length, pred, minimum, timeout); - StreamInfo[] res = new StreamInfo[num]; - for (int k = 0; k < num; k++) - res[k] = new StreamInfo(buf[k]); - return res; - } - - - // ====================== - // ==== Stream Inlet ==== - // ====================== - - /** - * A stream inlet. - * Inlets are used to receive streaming data (and meta-data) from the lab network. - */ - public class StreamInlet - { - /** - * Construct a new stream inlet from a resolved stream info. - * @param info A resolved stream info object (as coming from one of the resolver functions). - * Note: the stream_inlet may also be constructed with a fully-specified stream_info, - * if the desired channel format and count is already known up-front, but this is - * strongly discouraged and should only ever be done if there is no time to resolve the - * stream up-front (e.g., due to limitations in the client program). - * @param max_buflen Optionally the maximum amount of data to buffer (in seconds if there is a nominal - * sampling rate, otherwise x100 in samples). Recording applications want to use a fairly - * large buffer size here, while real-time applications would only buffer as much as - * they need to perform their next calculation. - * @param max_chunklen Optionally the maximum size, in samples, at which chunks are transmitted - * (the default corresponds to the chunk sizes used by the sender). - * Recording applications can use a generous size here (leaving it to the network how - * to pack things), while real-time applications may want a finer (perhaps 1-sample) granularity. - If left unspecified (=0), the sender determines the chunk granularity. - * @param recover Try to silently recover lost streams that are recoverable (=those that that have a source_id set). - * In all other cases (recover is false or the stream is not recoverable) functions may throw a - * LostException if the stream's source is lost (e.g., due to an app or computer crash). - */ - public StreamInlet(StreamInfo info) { obj = dll.lsl_create_inlet(info.handle(), 360, 0, 1); } - public StreamInlet(StreamInfo info, int max_buflen) { obj = dll.lsl_create_inlet(info.handle(), max_buflen, 0, 1); } - public StreamInlet(StreamInfo info, int max_buflen, int max_chunklen) { obj = dll.lsl_create_inlet(info.handle(), max_buflen, max_chunklen, 1); } - public StreamInlet(StreamInfo info, int max_buflen, int max_chunklen, bool recover) { obj = dll.lsl_create_inlet(info.handle(), max_buflen, max_chunklen, recover ? 1 : 0); } - - /** - * Destructor. - * The inlet will automatically disconnect if destroyed. - */ - ~StreamInlet() { dll.lsl_destroy_inlet(obj); } - - /** - * Retrieve the complete information of the given stream, including the extended description. - * Can be invoked at any time of the stream's lifetime. - * @param timeout Timeout of the operation (default: no timeout). - * @throws TimeoutException (if the timeout expires), or LostException (if the stream source has been lost). - */ - public StreamInfo info() { return info(FOREVER); } - public StreamInfo info(double timeout) { int ec = 0; IntPtr res = dll.lsl_get_fullinfo(obj, timeout, ref ec); check_error(ec); return new StreamInfo(res); } - - /** - * Subscribe to the data stream. - * All samples pushed in at the other end from this moment onwards will be queued and - * eventually be delivered in response to pull_sample() or pull_chunk() calls. - * Pulling a sample without some preceding open_stream is permitted (the stream will then be opened implicitly). - * @param timeout Optional timeout of the operation (default: no timeout). - * @throws TimeoutException (if the timeout expires), or LostException (if the stream source has been lost). - */ - public void open_stream() { open_stream(FOREVER); } - public void open_stream(double timeout) { int ec = 0; dll.lsl_open_stream(obj, timeout, ref ec); check_error(ec); } - - /** - * Drop the current data stream. - * All samples that are still buffered or in flight will be dropped and transmission - * and buffering of data for this inlet will be stopped. If an application stops being - * interested in data from a source (temporarily or not) but keeps the outlet alive, - * it should call close_stream() to not waste unnecessary system and network - * resources. - */ - public void close_stream() { dll.lsl_close_stream(obj); } - - /** - * Retrieve an estimated time correction offset for the given stream. - * The first call to this function takes several miliseconds until a reliable first estimate is obtained. - * Subsequent calls are instantaneous (and rely on periodic background updates). - * The precision of these estimates should be below 1 ms (empirically within +/-0.2 ms). - * @timeout Timeout to acquire the first time-correction estimate (default: no timeout). - * @return The time correction estimate. This is the number that needs to be added to a time stamp - * that was remotely generated via lsl_local_clock() to map it into the local clock domain of this machine. - * @throws TimeoutException (if the timeout expires), or LostException (if the stream source has been lost). - */ - public double time_correction() { return time_correction(FOREVER); } - public double time_correction(double timeout) { int ec = 0; double res = dll.lsl_time_correction(obj, timeout, ref ec); check_error(ec); return res; } - - // ======================================= - // === Pulling a sample from the inlet === - // ======================================= - - /** - * Pull a sample from the inlet and read it into an array of values. - * Handles type checking & conversion. - * @param sample An array to hold the resulting values. - * @param timeout The timeout for this operation, if any. Use 0.0 to make the function non-blocking. - * @return The capture time of the sample on the remote machine, or 0.0 if no new sample was available. - * To remap this time stamp to the local clock, add the value returned by .time_correction() to it. - * @throws LostException (if the stream source has been lost). - */ - public double pull_sample(float[] sample) { return pull_sample(sample, FOREVER); } - public double pull_sample(float[] sample, double timeout) { int ec = 0; double res = dll.lsl_pull_sample_f(obj, sample, sample.Length, timeout, ref ec); check_error(ec); return res; } - public double pull_sample(double[] sample) { return pull_sample(sample, FOREVER); } - public double pull_sample(double[] sample, double timeout) { int ec = 0; double res = dll.lsl_pull_sample_d(obj, sample, sample.Length, timeout, ref ec); check_error(ec); return res; } - public double pull_sample(int[] sample) { return pull_sample(sample, FOREVER); } - public double pull_sample(int[] sample, double timeout) { int ec = 0; double res = dll.lsl_pull_sample_i(obj, sample, sample.Length, timeout, ref ec); check_error(ec); return res; } - public double pull_sample(short[] sample) { return pull_sample(sample, FOREVER); } - public double pull_sample(short[] sample, double timeout) { int ec = 0; double res = dll.lsl_pull_sample_s(obj, sample, sample.Length, timeout, ref ec); check_error(ec); return res; } - public double pull_sample(char[] sample) { return pull_sample(sample, FOREVER); } - public double pull_sample(char[] sample, double timeout) { int ec = 0; double res = dll.lsl_pull_sample_c(obj, sample, sample.Length, timeout, ref ec); check_error(ec); return res; } - public double pull_sample(string[] sample) { return pull_sample(sample, FOREVER); } - public double pull_sample(string[] sample, double timeout) - { - int ec = 0; - IntPtr[] tmp = new IntPtr[sample.Length]; - double res = dll.lsl_pull_sample_str(obj, tmp, tmp.Length, timeout, ref ec); check_error(ec); - try - { - for (int k = 0; k < tmp.Length; k++) - sample[k] = Marshal.PtrToStringAnsi(tmp[k]); - } - finally - { - for (int k = 0; k < tmp.Length; k++) - dll.lsl_destroy_string(tmp[k]); - } - return res; - } - - - // ================================================= - // === Pulling a chunk of samples from the inlet === - // ================================================= - - /** - * Pull a chunk of data from the inlet. - * @param data_buffer A pre-allocated buffer where the channel data shall be stored. - * @param timestamp_buffer A pre-allocated buffer where time stamps shall be stored. - * @param timeout Optionally the timeout for this operation, if any. When the timeout expires, the function - * may return before the entire buffer is filled. The default value of 0.0 will retrieve only - * data available for immediate pickup. - * @return samples_written Number of samples written to the data and timestamp buffers. - * @throws LostException (if the stream source has been lost). - */ - public int pull_chunk(float[,] data_buffer, double[] timestamp_buffer) { return pull_chunk(data_buffer, timestamp_buffer, 0.0); } - public int pull_chunk(float[,] data_buffer, double[] timestamp_buffer, double timeout) { int ec = 0; uint res = dll.lsl_pull_chunk_f(obj, data_buffer, timestamp_buffer, (uint)data_buffer.Length, (uint)timestamp_buffer.Length, timeout, ref ec); check_error(ec); return (int)res / data_buffer.GetLength(1); } - public int pull_chunk(double[,] data_buffer, double[] timestamp_buffer) { return pull_chunk(data_buffer, timestamp_buffer, 0.0); } - public int pull_chunk(double[,] data_buffer, double[] timestamp_buffer, double timeout) { int ec = 0; uint res = dll.lsl_pull_chunk_d(obj, data_buffer, timestamp_buffer, (uint)data_buffer.Length, (uint)timestamp_buffer.Length, timeout, ref ec); check_error(ec); return (int)res / data_buffer.GetLength(1); } - public int pull_chunk(int[,] data_buffer, double[] timestamp_buffer) { return pull_chunk(data_buffer, timestamp_buffer, 0.0); } - public int pull_chunk(int[,] data_buffer, double[] timestamp_buffer, double timeout) { int ec = 0; uint res = dll.lsl_pull_chunk_i(obj, data_buffer, timestamp_buffer, (uint)data_buffer.Length, (uint)timestamp_buffer.Length, timeout, ref ec); check_error(ec); return (int)res / data_buffer.GetLength(1); } - public int pull_chunk(short[,] data_buffer, double[] timestamp_buffer) { return pull_chunk(data_buffer, timestamp_buffer, 0.0); } - public int pull_chunk(short[,] data_buffer, double[] timestamp_buffer, double timeout) { int ec = 0; uint res = dll.lsl_pull_chunk_s(obj, data_buffer, timestamp_buffer, (uint)data_buffer.Length, (uint)timestamp_buffer.Length, timeout, ref ec); check_error(ec); return (int)res / data_buffer.GetLength(1); } - public int pull_chunk(char[,] data_buffer, double[] timestamp_buffer) { return pull_chunk(data_buffer, timestamp_buffer, 0.0); } - public int pull_chunk(char[,] data_buffer, double[] timestamp_buffer, double timeout) { int ec = 0; uint res = dll.lsl_pull_chunk_c(obj, data_buffer, timestamp_buffer, (uint)data_buffer.Length, (uint)timestamp_buffer.Length, timeout, ref ec); check_error(ec); return (int)res / data_buffer.GetLength(1); } - public int pull_chunk(string[,] data_buffer, double[] timestamp_buffer) { return pull_chunk(data_buffer, timestamp_buffer, 0.0); } - public int pull_chunk(string[,] data_buffer, double[] timestamp_buffer, double timeout) - { - int ec = 0; - IntPtr[,] tmp = new IntPtr[data_buffer.GetLength(0), data_buffer.GetLength(1)]; - uint res = dll.lsl_pull_chunk_str(obj, tmp, timestamp_buffer, (uint)tmp.Length, (uint)timestamp_buffer.Length, timeout, ref ec); - check_error(ec); - try - { - for (int s = 0; s < tmp.GetLength(0); s++) - for (int c = 0; c < tmp.GetLength(1); c++) - data_buffer[s, c] = Marshal.PtrToStringAnsi(tmp[s, c]); - } - finally - { - for (int s = 0; s < tmp.GetLength(0); s++) - for (int c = 0; c < tmp.GetLength(1); c++) - dll.lsl_destroy_string(tmp[s, c]); - } - return (int)res / data_buffer.GetLength(1); - } - - /** - * Query whether samples are currently available for immediate pickup. - * Note that it is not a good idea to use samples_available() to determine whether - * a pull_*() call would block: to be sure, set the pull timeout to 0.0 or an acceptably - * low value. If the underlying implementation supports it, the value will be the number of - * samples available (otherwise it will be 1 or 0). - */ - public int samples_available() { return (int)dll.lsl_samples_available(obj); } - - /** - * Query whether the clock was potentially reset since the last call to was_clock_reset(). - * This is a rarely-used function that is only useful to applications that combine multiple time_correction - * values to estimate precise clock drift; it allows to tolerate cases where the source machine was - * hot-swapped or restarted in between two measurements. - */ - public bool was_clock_reset() { return (int)dll.lsl_was_clock_reset(obj) != 0; } - - private IntPtr obj; - } - - - // ===================== - // ==== XML Element ==== - // ===================== - - /** - * A lightweight XML element tree; models the .desc() field of stream_info. - * Has a name and can have multiple named children or have text content as value; attributes are omitted. - * Insider note: The interface is modeled after a subset of pugixml's node type and is compatible with it. - * See also http://pugixml.googlecode.com/svn/tags/latest/docs/manual/access.html for additional documentation. - */ - public struct XMLElement - { - public XMLElement(IntPtr handle) { obj = handle; } - - // === Tree Navigation === - - /// Get the first child of the element. - public XMLElement first_child() { return new XMLElement(dll.lsl_first_child(obj)); } - - /// Get the last child of the element. - public XMLElement last_child() { return new XMLElement(dll.lsl_last_child(obj)); } - - /// Get the next sibling in the children list of the parent node. - public XMLElement next_sibling() { return new XMLElement(dll.lsl_next_sibling(obj)); } - - /// Get the previous sibling in the children list of the parent node. - public XMLElement previous_sibling() { return new XMLElement(dll.lsl_previous_sibling(obj)); } - - /// Get the parent node. - public XMLElement parent() { return new XMLElement(dll.lsl_parent(obj)); } - - - // === Tree Navigation by Name === - - /// Get a child with a specified name. - public XMLElement child(string name) { return new XMLElement(dll.lsl_child(obj, name)); } - - /// Get the next sibling with the specified name. - public XMLElement next_sibling(string name) { return new XMLElement(dll.lsl_next_sibling_n(obj, name)); } - - /// Get the previous sibling with the specified name. - public XMLElement previous_sibling(string name) { return new XMLElement(dll.lsl_previous_sibling_n(obj, name)); } - - - // === Content Queries === - - /// Whether this node is empty. - public bool empty() { return dll.lsl_empty(obj) != 0; } - - /// Whether this is a text body (instead of an XML element). True both for plain char data and CData. - public bool is_text() { return dll.lsl_is_text(obj) != 0; } - - /// Name of the element. - public string name() { return Marshal.PtrToStringAnsi(dll.lsl_name(obj)); } - - /// Value of the element. - public string value() { return Marshal.PtrToStringAnsi(dll.lsl_value(obj)); } - - /// Get child value (value of the first child that is text). - public string child_value() { return Marshal.PtrToStringAnsi(dll.lsl_child_value(obj)); } - - /// Get child value of a child with a specified name. - public string child_value(string name) { return Marshal.PtrToStringAnsi(dll.lsl_child_value_n(obj, name)); } - - - // === Modification === - - /** - * Append a child node with a given name, which has a (nameless) plain-text child with the given text value. - */ - public XMLElement append_child_value(string name, string value) { return new XMLElement(dll.lsl_append_child_value(obj, name, value)); } - - /** - * Prepend a child node with a given name, which has a (nameless) plain-text child with the given text value. - */ - public XMLElement prepend_child_value(string name, string value) { return new XMLElement(dll.lsl_prepend_child_value(obj, name, value)); } - - /** - * Set the text value of the (nameless) plain-text child of a named child node. - */ - public bool set_child_value(string name, string value) { return dll.lsl_set_child_value(obj, name, value) != 0; } - - /** - * Set the element's name. - * @return False if the node is empty. - */ - public bool set_name(string rhs) { return dll.lsl_set_name(obj, rhs) != 0; } - - /** - * Set the element's value. - * @return False if the node is empty. - */ - public bool set_value(string rhs) { return dll.lsl_set_value(obj, rhs) != 0; } - - /// Append a child element with the specified name. - public XMLElement append_child(string name) { return new XMLElement(dll.lsl_append_child(obj, name)); } - - /// Prepend a child element with the specified name. - public XMLElement prepend_child(string name) { return new XMLElement(dll.lsl_prepend_child(obj, name)); } - - /// Append a copy of the specified element as a child. - public XMLElement append_copy(XMLElement e) { return new XMLElement(dll.lsl_append_copy(obj, e.obj)); } - - /// Prepend a child element with the specified name. - public XMLElement prepend_copy(XMLElement e) { return new XMLElement(dll.lsl_prepend_copy(obj, e.obj)); } - - /// Remove a child element with the specified name. - public void remove_child(string name) { dll.lsl_remove_child_n(obj, name); } - - /// Remove a specified child element. - public void remove_child(XMLElement e) { dll.lsl_remove_child(obj, e.obj); } - - IntPtr obj; - } - - - // =========================== - // === Continuous Resolver === - // =========================== - - /** - * A convenience class that resolves streams continuously in the background throughout - * its lifetime and which can be queried at any time for the set of streams that are currently - * visible on the network. - */ - - public class ContinuousResolver - { - /** - * Construct a new continuous_resolver that resolves all streams on the network. - * This is analogous to the functionality offered by the free function resolve_streams(). - * @param forget_after When a stream is no longer visible on the network (e.g., because it was shut down), - * this is the time in seconds after which it is no longer reported by the resolver. - */ - public ContinuousResolver() { obj = dll.lsl_create_continuous_resolver(5.0); } - public ContinuousResolver(double forget_after) { obj = dll.lsl_create_continuous_resolver(forget_after); } - - /** - * Construct a new continuous_resolver that resolves all streams with a specific value for a given property. - * This is analogous to the functionality provided by the free function resolve_stream(prop,value). - * @param prop The stream_info property that should have a specific value (e.g., "name", "type", "source_id", or "desc/manufaturer"). - * @param value The string value that the property should have (e.g., "EEG" as the type property). - * @param forget_after When a stream is no longer visible on the network (e.g., because it was shut down), - * this is the time in seconds after which it is no longer reported by the resolver. - */ - public ContinuousResolver(string prop, string value) { obj = dll.lsl_create_continuous_resolver_byprop(prop, value, 5.0); } - public ContinuousResolver(string prop, string value, double forget_after) { obj = dll.lsl_create_continuous_resolver_byprop(prop, value, forget_after); } - - /** - * Construct a new continuous_resolver that resolves all streams that match a given XPath 1.0 predicate. - * This is analogous to the functionality provided by the free function resolve_stream(pred). - * @param pred The predicate string, e.g. "name='BioSemi'" or "type='EEG' and starts-with(name,'BioSemi') and count(info/desc/channel)=32" - * @param forget_after When a stream is no longer visible on the network (e.g., because it was shut down), - * this is the time in seconds after which it is no longer reported by the resolver. - */ - public ContinuousResolver(string pred) { obj = dll.lsl_create_continuous_resolver_bypred(pred, 5.0); } - public ContinuousResolver(string pred, double forget_after) { obj = dll.lsl_create_continuous_resolver_bypred(pred, forget_after); } - - /** - * Destructor. - */ - ~ContinuousResolver() { dll.lsl_destroy_continuous_resolver(obj); } - - /** - * Obtain the set of currently present streams on the network (i.e. resolve result). - * @return An array of matching stream info objects (excluding their meta-data), any of - * which can subsequently be used to open an inlet. - */ - public StreamInfo[] results() - { - IntPtr[] buf = new IntPtr[1024]; - int num = dll.lsl_resolver_results(obj, buf, (uint)buf.Length); - StreamInfo[] res = new StreamInfo[num]; - for (int k = 0; k < num; k++) - res[k] = new StreamInfo(buf[k]); - return res; - } - - private IntPtr obj; - } - - // ======================= - // === Exception Types === - // ======================= - - /** - * Exception class that indicates that a stream inlet's source has been irrecoverably lost. - */ - public class LostException : System.Exception - { - public LostException() { } - public LostException(string message) { } - public LostException(string message, System.Exception inner) { } - protected LostException(System.Runtime.Serialization.SerializationInfo info, - System.Runtime.Serialization.StreamingContext context) - { } - } - - /** - * Exception class that indicates that an internal error has occurred inside liblsl. - */ - public class InternalException : System.Exception - { - public InternalException() { } - public InternalException(string message) { } - public InternalException(string message, System.Exception inner) { } - protected InternalException(System.Runtime.Serialization.SerializationInfo info, - System.Runtime.Serialization.StreamingContext context) - { } - } - - /** - * Check an error condition and throw an exception if appropriate. - */ - public static void check_error(int ec) - { - if (ec < 0) - switch (ec) - { - case -1: throw new TimeoutException("The operation failed due to a timeout."); - case -2: throw new LostException("The stream has been lost."); - case -3: throw new ArgumentException("An argument was incorrectly specified (e.g., wrong format or wrong length)."); - case -4: throw new InternalException("An internal internal error has occurred."); - default: throw new Exception("An unknown error has occurred."); - } - } - - - - // === Internal: C library function definitions. === - - class dll - { - #if (UNITY_EDITOR_WIN && UNITY_EDITOR_64) || (UNITY_EDITOR_LINUX && UNITY_EDITOR_64) || (UNITY_EDITOR_OSX && UNITY_EDITOR_64) - const string pathToAllLibs = "Assets/LSL4Unity/lib/"; + const string pathToAllLibs = "Assets/LSL4Unity/lib/"; #elif UNITY_STANDALONE_WIN || UNITY_STANDALONE_LINUX || UNITY_STANDALONE_OSX - const string pathToAllLibs = "../Plugins/"; + const string pathToAllLibs = "../Plugins/"; #elif UNITY_ANDROID - const string pathToAllLibs = ""; + const string pathToAllLibs = ""; #endif #if (UNITY_EDITOR_WIN && UNITY_EDITOR_64) - const string libname = "liblsl64.dll"; + const string libname = "liblsl64.dll"; #elif UNITY_EDITOR_WIN - const string libname = "liblsl32.dll"; + const string libname = "liblsl32.dll"; #elif UNITY_STANDALONE_WIN - // a build hook will took care that the correct dll will be renamed after a successfull build - const string libname = "liblsl.dll"; + // a build hook will took care that the correct dll will be renamed after a successfull build + const string libname = "liblsl.dll"; #elif (UNITY_EDITOR_LINUX && UNITY_EDITOR_64) || UNITY_STANDALONE_LINUX - const string libname = "liblsl64.so"; + const string libname = "liblsl64.so"; #elif UNITY_EDITOR_LINUX - const string libname = "liblsl32.so"; + const string libname = "liblsl32.so"; #elif UNITY_STANDALONE_LINUX - const string libname = "liblsl.so"; -#elif (Unity_EDITOR_OSX && UNITY_EDITOR_64) || UNITY_STANDALONE_OSX - const string libname = "liblsl64.bundle"; -#elif Unity_EDITOR_OSX - const string libname = "liblsl32.bundle"; + const string libname = "liblsl.so"; +#elif Unity_EDITOR_OSX || UNITY_STANDALONE_OSX + //32-bit dylib no longer provided. + const string libname = "liblsl64.bundle"; #elif UNITY_STANDALONE_OSX - const string libname = "liblsl.bundle"; + const string libname = "liblsl.bundle"; #elif UNITY_ANDROID - const string libname = "lslAndroid"; + const string libname = "lslAndroid"; #endif - const string pathToLib = pathToAllLibs + libname; + const string pathToLib = pathToAllLibs + libname; - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_protocol_version(); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_protocol_version(); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_library_version(); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_library_version(); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern double lsl_local_clock(); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern double lsl_local_clock(); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_create_streaminfo(string name, string type, int channel_count, double nominal_srate, channel_format_t channel_format, string source_id); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_create_streaminfo(string name, string type, int channel_count, double nominal_srate, channel_format_t channel_format, string source_id); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_destroy_streaminfo(IntPtr info); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_destroy_streaminfo(IntPtr info); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_get_name(IntPtr info); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_get_name(IntPtr info); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_get_type(IntPtr info); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_get_type(IntPtr info); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_get_channel_count(IntPtr info); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_get_channel_count(IntPtr info); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern double lsl_get_nominal_srate(IntPtr info); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern double lsl_get_nominal_srate(IntPtr info); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern channel_format_t lsl_get_channel_format(IntPtr info); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern channel_format_t lsl_get_channel_format(IntPtr info); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_get_source_id(IntPtr info); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_get_source_id(IntPtr info); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_get_version(IntPtr info); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_get_version(IntPtr info); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern double lsl_get_created_at(IntPtr info); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern double lsl_get_created_at(IntPtr info); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_get_uid(IntPtr info); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_get_uid(IntPtr info); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_get_session_id(IntPtr info); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_get_session_id(IntPtr info); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_get_hostname(IntPtr info); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_get_hostname(IntPtr info); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_get_desc(IntPtr info); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_get_desc(IntPtr info); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_get_xml(IntPtr info); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_get_xml(IntPtr info); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_create_outlet(IntPtr info, int chunk_size, int max_buffered); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_create_outlet(IntPtr info, int chunk_size, int max_buffered); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern void lsl_destroy_outlet(IntPtr obj); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern void lsl_destroy_outlet(IntPtr obj); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_push_sample_ftp(IntPtr obj, float[] data, double timestamp, int pushthrough); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_push_sample_ftp(IntPtr obj, float[] data, double timestamp, int pushthrough); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_push_sample_dtp(IntPtr obj, double[] data, double timestamp, int pushthrough); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_push_sample_dtp(IntPtr obj, double[] data, double timestamp, int pushthrough); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_push_sample_itp(IntPtr obj, int[] data, double timestamp, int pushthrough); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_push_sample_itp(IntPtr obj, int[] data, double timestamp, int pushthrough); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_push_sample_stp(IntPtr obj, short[] data, double timestamp, int pushthrough); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_push_sample_stp(IntPtr obj, short[] data, double timestamp, int pushthrough); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_push_sample_ctp(IntPtr obj, char[] data, double timestamp, int pushthrough); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_push_sample_ctp(IntPtr obj, char[] data, double timestamp, int pushthrough); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_push_sample_strtp(IntPtr obj, string[] data, double timestamp, int pushthrough); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_push_sample_strtp(IntPtr obj, string[] data, double timestamp, int pushthrough); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_push_sample_buftp(IntPtr obj, char[][] data, uint[] lengths, double timestamp, int pushthrough); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_push_sample_buftp(IntPtr obj, char[][] data, uint[] lengths, double timestamp, int pushthrough); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_push_chunk_ftp(IntPtr obj, float[,] data, uint data_elements, double timestamp, int pushthrough); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_push_chunk_ftp(IntPtr obj, float[,] data, uint data_elements, double timestamp, int pushthrough); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_push_chunk_ftnp(IntPtr obj, float[,] data, uint data_elements, double[] timestamps, int pushthrough); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_push_chunk_ftnp(IntPtr obj, float[,] data, uint data_elements, double[] timestamps, int pushthrough); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_push_chunk_dtp(IntPtr obj, double[,] data, uint data_elements, double timestamp, int pushthrough); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_push_chunk_dtp(IntPtr obj, double[,] data, uint data_elements, double timestamp, int pushthrough); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_push_chunk_dtnp(IntPtr obj, double[,] data, uint data_elements, double[] timestamps, int pushthrough); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_push_chunk_dtnp(IntPtr obj, double[,] data, uint data_elements, double[] timestamps, int pushthrough); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_push_chunk_itp(IntPtr obj, int[,] data, uint data_elements, double timestamp, int pushthrough); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_push_chunk_itp(IntPtr obj, int[,] data, uint data_elements, double timestamp, int pushthrough); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_push_chunk_itnp(IntPtr obj, int[,] data, uint data_elements, double[] timestamps, int pushthrough); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_push_chunk_itnp(IntPtr obj, int[,] data, uint data_elements, double[] timestamps, int pushthrough); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_push_chunk_stp(IntPtr obj, short[,] data, uint data_elements, double timestamp, int pushthrough); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_push_chunk_stp(IntPtr obj, short[,] data, uint data_elements, double timestamp, int pushthrough); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_push_chunk_stnp(IntPtr obj, short[,] data, uint data_elements, double[] timestamps, int pushthrough); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_push_chunk_stnp(IntPtr obj, short[,] data, uint data_elements, double[] timestamps, int pushthrough); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_push_chunk_ctp(IntPtr obj, char[,] data, uint data_elements, double timestamp, int pushthrough); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_push_chunk_ctp(IntPtr obj, char[,] data, uint data_elements, double timestamp, int pushthrough); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_push_chunk_ctnp(IntPtr obj, char[,] data, uint data_elements, double[] timestamps, int pushthrough); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_push_chunk_ctnp(IntPtr obj, char[,] data, uint data_elements, double[] timestamps, int pushthrough); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_push_chunk_strtp(IntPtr obj, string[,] data, uint data_elements, double timestamp, int pushthrough); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_push_chunk_strtp(IntPtr obj, string[,] data, uint data_elements, double timestamp, int pushthrough); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_push_chunk_strtnp(IntPtr obj, string[,] data, uint data_elements, double[] timestamps, int pushthrough); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_push_chunk_strtnp(IntPtr obj, string[,] data, uint data_elements, double[] timestamps, int pushthrough); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_push_chunk_buftp(IntPtr obj, char[][] data, uint[] lengths, uint data_elements, double timestamp, int pushthrough); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_push_chunk_buftp(IntPtr obj, char[][] data, uint[] lengths, uint data_elements, double timestamp, int pushthrough); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_push_chunk_buftnp(IntPtr obj, char[][] data, uint[] lengths, uint data_elements, double[] timestamps, int pushthrough); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_push_chunk_buftnp(IntPtr obj, char[][] data, uint[] lengths, uint data_elements, double[] timestamps, int pushthrough); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_have_consumers(IntPtr obj); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_have_consumers(IntPtr obj); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_wait_for_consumers(IntPtr obj); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_wait_for_consumers(IntPtr obj); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_get_info(IntPtr obj); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_get_info(IntPtr obj); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_resolve_all(IntPtr[] buffer, uint buffer_elements, double wait_time); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_resolve_all(IntPtr[] buffer, uint buffer_elements, double wait_time); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_resolve_byprop(IntPtr[] buffer, uint buffer_elements, string prop, string value, int minimum, double wait_time); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_resolve_byprop(IntPtr[] buffer, uint buffer_elements, string prop, string value, int minimum, double wait_time); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_resolve_bypred(IntPtr[] buffer, uint buffer_elements, string pred, int minimum, double wait_time); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_resolve_bypred(IntPtr[] buffer, uint buffer_elements, string pred, int minimum, double wait_time); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_create_inlet(IntPtr info, int max_buflen, int max_chunklen, int recover); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_create_inlet(IntPtr info, int max_buflen, int max_chunklen, int recover); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern void lsl_destroy_inlet(IntPtr obj); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern void lsl_destroy_inlet(IntPtr obj); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_get_fullinfo(IntPtr obj, double timeout, ref int ec); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_get_fullinfo(IntPtr obj, double timeout, ref int ec); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern void lsl_open_stream(IntPtr obj, double timeout, ref int ec); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern void lsl_open_stream(IntPtr obj, double timeout, ref int ec); + + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern void lsl_set_postprocessing(IntPtr obj, processing_options_t processing_flags); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern void lsl_close_stream(IntPtr obj); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern void lsl_close_stream(IntPtr obj); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern double lsl_time_correction(IntPtr obj, double timeout, ref int ec); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern double lsl_time_correction(IntPtr obj, double timeout, ref int ec); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern double lsl_pull_sample_f(IntPtr obj, float[] buffer, int buffer_elements, double timeout, ref int ec); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern double lsl_pull_sample_f(IntPtr obj, float[] buffer, int buffer_elements, double timeout, ref int ec); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern double lsl_pull_sample_d(IntPtr obj, double[] buffer, int buffer_elements, double timeout, ref int ec); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern double lsl_pull_sample_d(IntPtr obj, double[] buffer, int buffer_elements, double timeout, ref int ec); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern double lsl_pull_sample_i(IntPtr obj, int[] buffer, int buffer_elements, double timeout, ref int ec); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern double lsl_pull_sample_i(IntPtr obj, int[] buffer, int buffer_elements, double timeout, ref int ec); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern double lsl_pull_sample_s(IntPtr obj, short[] buffer, int buffer_elements, double timeout, ref int ec); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern double lsl_pull_sample_s(IntPtr obj, short[] buffer, int buffer_elements, double timeout, ref int ec); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern double lsl_pull_sample_c(IntPtr obj, char[] buffer, int buffer_elements, double timeout, ref int ec); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern double lsl_pull_sample_c(IntPtr obj, char[] buffer, int buffer_elements, double timeout, ref int ec); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern double lsl_pull_sample_str(IntPtr obj, IntPtr[] buffer, int buffer_elements, double timeout, ref int ec); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern double lsl_pull_sample_str(IntPtr obj, IntPtr[] buffer, int buffer_elements, double timeout, ref int ec); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern double lsl_pull_sample_buf(IntPtr obj, char[][] buffer, uint[] buffer_lengths, int buffer_elements, double timeout, ref int ec); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern double lsl_pull_sample_buf(IntPtr obj, char[][] buffer, uint[] buffer_lengths, int buffer_elements, double timeout, ref int ec); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern void lsl_destroy_string(IntPtr str); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern void lsl_destroy_string(IntPtr str); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern uint lsl_pull_chunk_f(IntPtr obj, float[,] data_buffer, double[] timestamp_buffer, uint data_buffer_elements, uint timestamp_buffer_elements, double timeout, ref int ec); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern uint lsl_pull_chunk_f(IntPtr obj, float[,] data_buffer, double[] timestamp_buffer, uint data_buffer_elements, uint timestamp_buffer_elements, double timeout, ref int ec); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern uint lsl_pull_chunk_d(IntPtr obj, double[,] data_buffer, double[] timestamp_buffer, uint data_buffer_elements, uint timestamp_buffer_elements, double timeout, ref int ec); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern uint lsl_pull_chunk_d(IntPtr obj, double[,] data_buffer, double[] timestamp_buffer, uint data_buffer_elements, uint timestamp_buffer_elements, double timeout, ref int ec); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern uint lsl_pull_chunk_i(IntPtr obj, int[,] data_buffer, double[] timestamp_buffer, uint data_buffer_elements, uint timestamp_buffer_elements, double timeout, ref int ec); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern uint lsl_pull_chunk_i(IntPtr obj, int[,] data_buffer, double[] timestamp_buffer, uint data_buffer_elements, uint timestamp_buffer_elements, double timeout, ref int ec); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern uint lsl_pull_chunk_s(IntPtr obj, short[,] data_buffer, double[] timestamp_buffer, uint data_buffer_elements, uint timestamp_buffer_elements, double timeout, ref int ec); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern uint lsl_pull_chunk_s(IntPtr obj, short[,] data_buffer, double[] timestamp_buffer, uint data_buffer_elements, uint timestamp_buffer_elements, double timeout, ref int ec); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern uint lsl_pull_chunk_c(IntPtr obj, char[,] data_buffer, double[] timestamp_buffer, uint data_buffer_elements, uint timestamp_buffer_elements, double timeout, ref int ec); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern uint lsl_pull_chunk_c(IntPtr obj, char[,] data_buffer, double[] timestamp_buffer, uint data_buffer_elements, uint timestamp_buffer_elements, double timeout, ref int ec); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern uint lsl_pull_chunk_str(IntPtr obj, IntPtr[,] data_buffer, double[] timestamp_buffer, uint data_buffer_elements, uint timestamp_buffer_elements, double timeout, ref int ec); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern uint lsl_pull_chunk_str(IntPtr obj, IntPtr[,] data_buffer, double[] timestamp_buffer, uint data_buffer_elements, uint timestamp_buffer_elements, double timeout, ref int ec); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern uint lsl_pull_chunk_buf(IntPtr obj, char[][,] data_buffer, uint[,] lengths_buffer, double[] timestamp_buffer, uint data_buffer_elements, uint timestamp_buffer_elements, double timeout, ref int ec); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern uint lsl_pull_chunk_buf(IntPtr obj, char[][,] data_buffer, uint[,] lengths_buffer, double[] timestamp_buffer, uint data_buffer_elements, uint timestamp_buffer_elements, double timeout, ref int ec); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern uint lsl_samples_available(IntPtr obj); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern uint lsl_samples_available(IntPtr obj); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern uint lsl_was_clock_reset(IntPtr obj); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern uint lsl_was_clock_reset(IntPtr obj); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_first_child(IntPtr e); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_first_child(IntPtr e); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_last_child(IntPtr e); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_last_child(IntPtr e); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_next_sibling(IntPtr e); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_next_sibling(IntPtr e); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_previous_sibling(IntPtr e); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_previous_sibling(IntPtr e); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_parent(IntPtr e); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_parent(IntPtr e); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_child(IntPtr e, string name); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_child(IntPtr e, string name); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_next_sibling_n(IntPtr e, string name); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_next_sibling_n(IntPtr e, string name); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_previous_sibling_n(IntPtr e, string name); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_previous_sibling_n(IntPtr e, string name); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_empty(IntPtr e); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_empty(IntPtr e); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_is_text(IntPtr e); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_is_text(IntPtr e); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_name(IntPtr e); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_name(IntPtr e); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_value(IntPtr e); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_value(IntPtr e); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_child_value(IntPtr e); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_child_value(IntPtr e); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_child_value_n(IntPtr e, string name); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_child_value_n(IntPtr e, string name); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_append_child_value(IntPtr e, string name, string value); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_append_child_value(IntPtr e, string name, string value); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_prepend_child_value(IntPtr e, string name, string value); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_prepend_child_value(IntPtr e, string name, string value); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_set_child_value(IntPtr e, string name, string value); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_set_child_value(IntPtr e, string name, string value); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_set_name(IntPtr e, string rhs); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_set_name(IntPtr e, string rhs); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_set_value(IntPtr e, string rhs); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_set_value(IntPtr e, string rhs); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_append_child(IntPtr e, string name); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_append_child(IntPtr e, string name); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_prepend_child(IntPtr e, string name); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_prepend_child(IntPtr e, string name); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_append_copy(IntPtr e, IntPtr e2); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_append_copy(IntPtr e, IntPtr e2); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_prepend_copy(IntPtr e, IntPtr e2); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_prepend_copy(IntPtr e, IntPtr e2); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern void lsl_remove_child_n(IntPtr e, string name); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern void lsl_remove_child_n(IntPtr e, string name); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern void lsl_remove_child(IntPtr e, IntPtr e2); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern void lsl_remove_child(IntPtr e, IntPtr e2); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_create_continuous_resolver(double forget_after); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_create_continuous_resolver(double forget_after); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_create_continuous_resolver_byprop(string prop, string value, double forget_after); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_create_continuous_resolver_byprop(string prop, string value, double forget_after); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern IntPtr lsl_create_continuous_resolver_bypred(string pred, double forget_after); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern IntPtr lsl_create_continuous_resolver_bypred(string pred, double forget_after); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern int lsl_resolver_results(IntPtr obj, IntPtr[] buffer, uint buffer_elements); + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern int lsl_resolver_results(IntPtr obj, IntPtr[] buffer, uint buffer_elements); - [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] - public static extern void lsl_destroy_continuous_resolver(IntPtr obj); - } + [DllImport(pathToLib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)] + public static extern void lsl_destroy_continuous_resolver(IntPtr obj); } } +} diff --git a/lib/liblsl32-debug.dll b/lib/liblsl32-debug.dll new file mode 100644 index 0000000000000000000000000000000000000000..3cf4509d6d4e89cdd8f723a9b40cf9561ec3f6f8 Binary files /dev/null and b/lib/liblsl32-debug.dll differ diff --git a/lib/liblsl32-debug.dll.meta b/lib/liblsl32-debug.dll.meta new file mode 100644 index 0000000000000000000000000000000000000000..1629e9bc30046b92f31d3efc7cc686a10ea93009 --- /dev/null +++ b/lib/liblsl32-debug.dll.meta @@ -0,0 +1,21 @@ +fileFormatVersion: 2 +guid: 67e3e0a631c08a34483ec2ce4b3fec93 +timeCreated: 1483046972 +licenseType: Free +PluginImporter: + serializedVersion: 1 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + Any: + enabled: 1 + settings: {} + Editor: + enabled: 0 + settings: + DefaultValueInitialized: true + userData: + assetBundleName: + assetBundleVariant: diff --git a/lib/liblsl32-debug.so b/lib/liblsl32-debug.so new file mode 100644 index 0000000000000000000000000000000000000000..43c0320975d90a8701fad4da6785ff666059d998 Binary files /dev/null and b/lib/liblsl32-debug.so differ diff --git a/lib/liblsl32-debug.so.meta b/lib/liblsl32-debug.so.meta new file mode 100644 index 0000000000000000000000000000000000000000..07d7c934f15f98ab356471a7586a42e3a5188d6d --- /dev/null +++ b/lib/liblsl32-debug.so.meta @@ -0,0 +1,21 @@ +fileFormatVersion: 2 +guid: 707426ef83403304981b3e6ccd055421 +timeCreated: 1483046972 +licenseType: Free +PluginImporter: + serializedVersion: 1 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + Any: + enabled: 1 + settings: {} + Editor: + enabled: 0 + settings: + DefaultValueInitialized: true + userData: + assetBundleName: + assetBundleVariant: diff --git a/lib/liblsl32.bundle b/lib/liblsl32.bundle deleted file mode 100644 index fb4e5eade88aa986511467cad08272eb97aefbf5..0000000000000000000000000000000000000000 Binary files a/lib/liblsl32.bundle and /dev/null differ diff --git a/lib/liblsl32.bundle.meta b/lib/liblsl32.bundle.meta deleted file mode 100644 index f7b06401f1c9f475cb44a07f1dd704440b3206ae..0000000000000000000000000000000000000000 --- a/lib/liblsl32.bundle.meta +++ /dev/null @@ -1,55 +0,0 @@ -fileFormatVersion: 2 -guid: 95220c9bcc641c743a7c8036d4bf6031 -folderAsset: yes -timeCreated: 1470341778 -licenseType: Free -PluginImporter: - serializedVersion: 1 - iconMap: {} - executionOrder: {} - isPreloaded: 0 - platformData: - Any: - enabled: 1 - settings: {} - Editor: - enabled: 0 - settings: - CPU: x86 - DefaultValueInitialized: true - OS: OSX - Linux: - enabled: 0 - settings: - CPU: x86 - Linux64: - enabled: 0 - settings: - CPU: x86_64 - LinuxUniversal: - enabled: 0 - settings: - CPU: None - OSXIntel: - enabled: 1 - settings: - CPU: AnyCPU - OSXIntel64: - enabled: 0 - settings: - CPU: AnyCPU - OSXUniversal: - enabled: 1 - settings: - CPU: x86 - Win: - enabled: 0 - settings: - CPU: AnyCPU - Win64: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/lib/liblsl32.dll b/lib/liblsl32.dll index 76a31345b640b2184fb4e7005833dd6abe06e009..a3d01c15ddd28277f5380f8809622fb1aaec9891 100644 Binary files a/lib/liblsl32.dll and b/lib/liblsl32.dll differ diff --git a/lib/liblsl32.dll.meta b/lib/liblsl32.dll.meta index ad73fe2158e900536982653bb7d389daa3c19dba..dbb0fafa2a4aeac5342eae15eb3b7f81c8c49820 100644 --- a/lib/liblsl32.dll.meta +++ b/lib/liblsl32.dll.meta @@ -1,12 +1,13 @@ fileFormatVersion: 2 guid: f6cc67f51caa986418929e0c0d3231c2 -timeCreated: 1470341778 +timeCreated: 1483042673 licenseType: Free PluginImporter: serializedVersion: 1 iconMap: {} executionOrder: {} isPreloaded: 0 + isOverridable: 0 platformData: Android: enabled: 0 diff --git a/lib/liblsl32.so b/lib/liblsl32.so index d7f28f33e7aad8e19918fcaa7b43d55ba770b1e0..c3221a7a2137d9387e18c748c6780d86ccf21884 100644 Binary files a/lib/liblsl32.so and b/lib/liblsl32.so differ diff --git a/lib/liblsl32.so.meta b/lib/liblsl32.so.meta index 72bc2bb92ac0552bb9a7672e3cee8249f61b3988..a196a7a2efd8bf8fc699757459c54cf7e8d54a51 100644 --- a/lib/liblsl32.so.meta +++ b/lib/liblsl32.so.meta @@ -1,12 +1,13 @@ fileFormatVersion: 2 guid: 1b73adaf564879840adf0ffe7d3bdd7d -timeCreated: 1470341778 +timeCreated: 1483042673 licenseType: Free PluginImporter: serializedVersion: 1 iconMap: {} executionOrder: {} isPreloaded: 0 + isOverridable: 0 platformData: Android: enabled: 0 diff --git a/lib/liblsl64-debug.bundle b/lib/liblsl64-debug.bundle new file mode 100644 index 0000000000000000000000000000000000000000..b7d091675b9cc9c234b2472317c350b7dcbf1ed7 Binary files /dev/null and b/lib/liblsl64-debug.bundle differ diff --git a/lib/liblsl64-debug.bundle.meta b/lib/liblsl64-debug.bundle.meta new file mode 100644 index 0000000000000000000000000000000000000000..46609b98389e56533151240a08c6b9ae4b694eeb --- /dev/null +++ b/lib/liblsl64-debug.bundle.meta @@ -0,0 +1,30 @@ +fileFormatVersion: 2 +guid: cdc469b93dbb93347800642eb6c18f93 +timeCreated: 1483046972 +licenseType: Free +PluginImporter: + serializedVersion: 1 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + Any: + enabled: 0 + settings: {} + Editor: + enabled: 1 + settings: + DefaultValueInitialized: true + OSXIntel: + enabled: 1 + settings: {} + OSXIntel64: + enabled: 1 + settings: {} + OSXUniversal: + enabled: 1 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/lib/liblsl64-debug.dll b/lib/liblsl64-debug.dll new file mode 100644 index 0000000000000000000000000000000000000000..8e8448174256be8ced6f77c76cfd2c896af40b7b Binary files /dev/null and b/lib/liblsl64-debug.dll differ diff --git a/lib/liblsl64-debug.dll.meta b/lib/liblsl64-debug.dll.meta new file mode 100644 index 0000000000000000000000000000000000000000..cd78f85f5f04b2082cfc1a043c4a99edcb57beeb --- /dev/null +++ b/lib/liblsl64-debug.dll.meta @@ -0,0 +1,21 @@ +fileFormatVersion: 2 +guid: e0b0d9a8fac9fd4458f05573189d2c1d +timeCreated: 1483046972 +licenseType: Free +PluginImporter: + serializedVersion: 1 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + Any: + enabled: 1 + settings: {} + Editor: + enabled: 0 + settings: + DefaultValueInitialized: true + userData: + assetBundleName: + assetBundleVariant: diff --git a/lib/liblsl64-debug.so b/lib/liblsl64-debug.so new file mode 100644 index 0000000000000000000000000000000000000000..d14b63c4da01e6d47dffc3680e45e861c1ebac9b Binary files /dev/null and b/lib/liblsl64-debug.so differ diff --git a/lib/liblsl64-debug.so.meta b/lib/liblsl64-debug.so.meta new file mode 100644 index 0000000000000000000000000000000000000000..8597101267c61e2e249b961ee587c1ecb7d242a2 --- /dev/null +++ b/lib/liblsl64-debug.so.meta @@ -0,0 +1,21 @@ +fileFormatVersion: 2 +guid: e90e957c1fa338c498e1d3999cf79992 +timeCreated: 1483046972 +licenseType: Free +PluginImporter: + serializedVersion: 1 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + Any: + enabled: 1 + settings: {} + Editor: + enabled: 0 + settings: + DefaultValueInitialized: true + userData: + assetBundleName: + assetBundleVariant: diff --git a/lib/liblsl64.bundle b/lib/liblsl64.bundle index 79c2f37dbdb6dbc87775c8773201f4d950cd6144..15eb8a49a0d0acd2864c8690b726213b3f806938 100644 Binary files a/lib/liblsl64.bundle and b/lib/liblsl64.bundle differ diff --git a/lib/liblsl64.bundle.meta b/lib/liblsl64.bundle.meta index e46363bd5b628b7c5b6de1ec56ef6fdb88067c55..c104eb7657d2948a4c570ba51e9ac9dd4a748596 100644 --- a/lib/liblsl64.bundle.meta +++ b/lib/liblsl64.bundle.meta @@ -1,55 +1,30 @@ fileFormatVersion: 2 -guid: f5ac749b583fd6f41b73e2c65b299ca6 -folderAsset: yes -timeCreated: 1470341778 +guid: 3468afafc3fa44e4e8e603f295ed45c1 +timeCreated: 1483045213 licenseType: Free PluginImporter: serializedVersion: 1 iconMap: {} executionOrder: {} isPreloaded: 0 + isOverridable: 0 platformData: Any: - enabled: 1 + enabled: 0 settings: {} Editor: - enabled: 0 + enabled: 1 settings: - CPU: x86_64 DefaultValueInitialized: true - OS: OSX - Linux: - enabled: 0 - settings: - CPU: x86 - Linux64: - enabled: 0 - settings: - CPU: x86_64 - LinuxUniversal: - enabled: 0 - settings: - CPU: None OSXIntel: - enabled: 0 - settings: - CPU: AnyCPU + enabled: 1 + settings: {} OSXIntel64: enabled: 1 - settings: - CPU: AnyCPU + settings: {} OSXUniversal: enabled: 1 - settings: - CPU: x86_64 - Win: - enabled: 0 - settings: - CPU: AnyCPU - Win64: - enabled: 0 - settings: - CPU: AnyCPU + settings: {} userData: assetBundleName: assetBundleVariant: diff --git a/lib/liblsl64.dll b/lib/liblsl64.dll index 582de7ccac3ecd77c833a19b3490c3930d410a7c..4285944650052f7519c17fece3d7ba4ef73454f0 100644 Binary files a/lib/liblsl64.dll and b/lib/liblsl64.dll differ diff --git a/lib/liblsl64.dll.meta b/lib/liblsl64.dll.meta index fb11d9471436151fd712c6589dad189842ce896e..69a783e8c64896f36f25c112bd9ccf30cb489cd5 100644 --- a/lib/liblsl64.dll.meta +++ b/lib/liblsl64.dll.meta @@ -1,12 +1,13 @@ fileFormatVersion: 2 guid: 9dd4bc2a970868b44b45538de402946e -timeCreated: 1470341778 +timeCreated: 1483042673 licenseType: Free PluginImporter: serializedVersion: 1 iconMap: {} executionOrder: {} isPreloaded: 0 + isOverridable: 0 platformData: Android: enabled: 0 diff --git a/lib/liblsl64.so b/lib/liblsl64.so index 3c10015ed8134a06f540a311a86d08874529b413..bf25b0192dc57b1fd5c807d861b0a430aa5e1b79 100644 Binary files a/lib/liblsl64.so and b/lib/liblsl64.so differ diff --git a/lib/liblsl64.so.meta b/lib/liblsl64.so.meta index c382f85b86478d8d6961672acfd3ab1da5159784..f60ccd3d598de252ba1fe7a7ae2ea49afe63519e 100644 --- a/lib/liblsl64.so.meta +++ b/lib/liblsl64.so.meta @@ -1,12 +1,13 @@ fileFormatVersion: 2 guid: ef79df50f092a57468401d6b4eac57d6 -timeCreated: 1470341778 +timeCreated: 1483042673 licenseType: Free PluginImporter: serializedVersion: 1 iconMap: {} executionOrder: {} isPreloaded: 0 + isOverridable: 0 platformData: Android: enabled: 0