Lab Streaming Layer (LSL) zur Synchronisierung mehrerer Datenströme

Roshini Randeniya

01.10.2025

Teilen:

von Roshini Randeniya und Lucas Kleine

Operation:
Sobald es in der Befehlszeile ausgeführt wird, initiiert dieses Skript sofort einen LSL-Stream. Jedes Mal, wenn die 'Enter'-Taste gedrückt wird, sendet es einen Trigger und spielt eine Audiodatei ab."""

import sounddevice as sd
import soundfile as sf
from pylsl import StreamInfo, StreamOutlet

def wait_for_keypress():
print("Drücken Sie ENTER, um die Audio-Wiedergabe zu starten und ein LSL-Marker zu senden.")

while True: # This loop waits for a keyboard input
    input_str = input()  # Wait for input from the terminal
    if input_str == "":  # If the enter key is pressed, proceed
        break

def AudioMarker(audio_file, outlet): # Funktion zum Abspielen von Audio und Senden eines Markers
data, fs = sf.read(audio_file) # Ladet die Audiodatei

print("Playing audio and sending LSL marker...")
marker_val = [1]
outlet.push_sample(marker_val) # Send marker indicating the start of audio playback
sd.play(data, fs) # play the audio
sd.wait()  # Wait until audio is done playing
print("Audio playback finished.")

if name == "main": # HAUPTSCHLEIFE
# LSL-Stream für Marker einrichten
stream_name = 'AudioMarkers'
stream_type = 'Markers'
n_chans = 1
sr = 0 # Setze die Abtastrate auf 0, da Marker unregelmäßig sind
chan_format = 'int32'
marker_id = 'uniqueMarkerID12345'

info = StreamInfo(stream_name, stream_type, n_chans, sr, chan_format, marker_id)
outlet = StreamOutlet(info) # create LSL outlet

# Keep the script running and wait for ENTER key to play audio and send marker
while True:
    wait_for_keypress()
    audio_filepath = "/path/to/your/audio_file.wav"  # replace with correct path to your audio file
    AudioMarker(audio_filepath, outlet)
    # After playing audio and sending a marker, the script goes back to waiting for the next keypress</code></pre><p><em><strong>**By running this file (even before playing the audio), you've initiated an LSL stream through an outlet</strong></em><strong>. Now we'll view that stream in LabRecorder</strong></p><p><strong>STEP 5 - Use LabRecorder to view and save all LSL streams</strong></p><ol><li data-preset-tag="p"><p>Open LabRecorder</p></li><li data-preset-tag="p"><p>Press <em><strong>Update</strong></em>. The available LSL streams should be visible in the stream list<br> • You should be able to see streams from both EmotivPROs (usually called "EmotivDataStream") and the marker stream (called "AudioMarkers")</p></li><li data-preset-tag="p"><p>Click <em><strong>Browse</strong></em> to select a location to store data (and set other parameters)</p></li><li data-preset-tag="p"><p>Select all streams and press <em><strong>Record</strong></em> to start recording</p></li><li data-preset-tag="p"><p>Click Stop when you want to end the recording</p></li></ol><p><br></p><img alt="" src="https://framerusercontent.com/images/HFGuJF9ErVu2Jxrgtqt11tl0No.jpg"><h2><strong>Working with the data</strong></h2><p><strong>LabRecorder outputs an XDF file (Extensible Data Format) that contains data from all the streams. XDF files are structured into, </strong><em><strong>streams</strong></em><strong>, each with a different </strong><em><strong>header</strong></em><strong> that describes what it contains (device name, data type, sampling rate, channels, and more). You can use the below codeblock to open your XDF file and display some basic information.</strong></p><pre data-language="JSX"><code>

Dieses Beispielskript demonstriert einige grundlegende Funktionen, um EEG-Daten zu importieren und zu annotieren, die mit der EmotivPRO-Software gesammelt wurden. Es verwendet MNE, um eine XDF-Datei zu laden, einige grundlegende Metadaten auszudrucken, ein info-Objekt zu erstellen und das Leistungsspektrum darzustellen."""

import pyxdf
import mne
import matplotlib.pyplot as plt
import numpy as np

Pfad zu Ihrer XDF-Datei

data_path = '/path/to/your/xdf_file.xdf'

XDF-Datei laden

streams, fileheader = pyxdf.load_xdf(data_path)
print("XDF-Datei-Header:", fileheader)
print("Anzahl der gefundenen Streams:", len(streams))

for i, stream in enumerate(streams):
print("\nStream", i + 1)
print("Stream-Name:", stream['info']['name'][0])
print("Stream-Typ:", stream['info']['type'][0])
print("Anzahl der Kanäle:", stream['info']['channel_count'][0])
sfreq = float(stream['info']['nominal_srate'][0])
print("Abtastrate:", sfreq)
print("Anzahl der Proben:", len(stream['time_series']))
print("Die ersten 5 Datenpunkte ausdrucken:", stream['time_series'][:5])

channel_names = [chan['label'][0] for chan in stream['info']['desc'][0]['channels'][0]['channel']]
print("Channel Names:", channel_names)
channel_types = 'eeg'

MNE-Info-Objekt erstellen

info = mne.create_info(channel_names, sfreq, channel_types)
data = np.array(stream['time_series']).T # Daten müssen transponiert werden: Kanäle x Proben
raw = mne.io.RawArray(data, info)
raw.plot_psd(fmax=50) # plotten Sie ein einfaches Spektrogramm (Leistungsspektraldichte)Zusätzliche RessourcenLaden Sie dieses Tutorial als Jupyter-Notebook von EMOTIV GitHub herunterSehen Sie sich die LSL Online-Dokumentation an, einschließlich der offiziellen README-Datei auf GitHubSie benötigen ein oder mehrere unterstützte Datenerfassungsgeräte zur DatensammlungAlle Brainware-Geräte von EMOTIV verbinden sich mit der EmotivPRO-Software, die über integrierte LSL-Funktionen zum Senden und Empfangen von Datenströmen verfügtZusätzliche Ressourcen:Code zur Ausführung von LSL mit Emovits Geräten, mit BeispielscriptenNützliche LSL-Demo auf YouTubeSCCN LSL GitHub-Repository für alle zugehörigen BibliothekenGitHub-Repository für eine Sammlung von Submodulen und AppsHyPyP-Analysepipeline für Hyperscanning-Studien

von Roshini Randeniya und Lucas Kleine

Operation:
Sobald es in der Befehlszeile ausgeführt wird, initiiert dieses Skript sofort einen LSL-Stream. Jedes Mal, wenn die 'Enter'-Taste gedrückt wird, sendet es einen Trigger und spielt eine Audiodatei ab."""

import sounddevice as sd
import soundfile as sf
from pylsl import StreamInfo, StreamOutlet

def wait_for_keypress():
print("Drücken Sie ENTER, um die Audio-Wiedergabe zu starten und ein LSL-Marker zu senden.")

while True: # This loop waits for a keyboard input
    input_str = input()  # Wait for input from the terminal
    if input_str == "":  # If the enter key is pressed, proceed
        break

def AudioMarker(audio_file, outlet): # Funktion zum Abspielen von Audio und Senden eines Markers
data, fs = sf.read(audio_file) # Ladet die Audiodatei

print("Playing audio and sending LSL marker...")
marker_val = [1]
outlet.push_sample(marker_val) # Send marker indicating the start of audio playback
sd.play(data, fs) # play the audio
sd.wait()  # Wait until audio is done playing
print("Audio playback finished.")

if name == "main": # HAUPTSCHLEIFE
# LSL-Stream für Marker einrichten
stream_name = 'AudioMarkers'
stream_type = 'Markers'
n_chans = 1
sr = 0 # Setze die Abtastrate auf 0, da Marker unregelmäßig sind
chan_format = 'int32'
marker_id = 'uniqueMarkerID12345'

info = StreamInfo(stream_name, stream_type, n_chans, sr, chan_format, marker_id)
outlet = StreamOutlet(info) # create LSL outlet

# Keep the script running and wait for ENTER key to play audio and send marker
while True:
    wait_for_keypress()
    audio_filepath = "/path/to/your/audio_file.wav"  # replace with correct path to your audio file
    AudioMarker(audio_filepath, outlet)
    # After playing audio and sending a marker, the script goes back to waiting for the next keypress</code></pre><p><em><strong>**By running this file (even before playing the audio), you've initiated an LSL stream through an outlet</strong></em><strong>. Now we'll view that stream in LabRecorder</strong></p><p><strong>STEP 5 - Use LabRecorder to view and save all LSL streams</strong></p><ol><li data-preset-tag="p"><p>Open LabRecorder</p></li><li data-preset-tag="p"><p>Press <em><strong>Update</strong></em>. The available LSL streams should be visible in the stream list<br> • You should be able to see streams from both EmotivPROs (usually called "EmotivDataStream") and the marker stream (called "AudioMarkers")</p></li><li data-preset-tag="p"><p>Click <em><strong>Browse</strong></em> to select a location to store data (and set other parameters)</p></li><li data-preset-tag="p"><p>Select all streams and press <em><strong>Record</strong></em> to start recording</p></li><li data-preset-tag="p"><p>Click Stop when you want to end the recording</p></li></ol><p><br></p><img alt="" src="https://framerusercontent.com/images/HFGuJF9ErVu2Jxrgtqt11tl0No.jpg"><h2><strong>Working with the data</strong></h2><p><strong>LabRecorder outputs an XDF file (Extensible Data Format) that contains data from all the streams. XDF files are structured into, </strong><em><strong>streams</strong></em><strong>, each with a different </strong><em><strong>header</strong></em><strong> that describes what it contains (device name, data type, sampling rate, channels, and more). You can use the below codeblock to open your XDF file and display some basic information.</strong></p><pre data-language="JSX"><code>

Dieses Beispielskript demonstriert einige grundlegende Funktionen, um EEG-Daten zu importieren und zu annotieren, die mit der EmotivPRO-Software gesammelt wurden. Es verwendet MNE, um eine XDF-Datei zu laden, einige grundlegende Metadaten auszudrucken, ein info-Objekt zu erstellen und das Leistungsspektrum darzustellen."""

import pyxdf
import mne
import matplotlib.pyplot as plt
import numpy as np

Pfad zu Ihrer XDF-Datei

data_path = '/path/to/your/xdf_file.xdf'

XDF-Datei laden

streams, fileheader = pyxdf.load_xdf(data_path)
print("XDF-Datei-Header:", fileheader)
print("Anzahl der gefundenen Streams:", len(streams))

for i, stream in enumerate(streams):
print("\nStream", i + 1)
print("Stream-Name:", stream['info']['name'][0])
print("Stream-Typ:", stream['info']['type'][0])
print("Anzahl der Kanäle:", stream['info']['channel_count'][0])
sfreq = float(stream['info']['nominal_srate'][0])
print("Abtastrate:", sfreq)
print("Anzahl der Proben:", len(stream['time_series']))
print("Die ersten 5 Datenpunkte ausdrucken:", stream['time_series'][:5])

channel_names = [chan['label'][0] for chan in stream['info']['desc'][0]['channels'][0]['channel']]
print("Channel Names:", channel_names)
channel_types = 'eeg'

MNE-Info-Objekt erstellen

info = mne.create_info(channel_names, sfreq, channel_types)
data = np.array(stream['time_series']).T # Daten müssen transponiert werden: Kanäle x Proben
raw = mne.io.RawArray(data, info)
raw.plot_psd(fmax=50) # plotten Sie ein einfaches Spektrogramm (Leistungsspektraldichte)Zusätzliche RessourcenLaden Sie dieses Tutorial als Jupyter-Notebook von EMOTIV GitHub herunterSehen Sie sich die LSL Online-Dokumentation an, einschließlich der offiziellen README-Datei auf GitHubSie benötigen ein oder mehrere unterstützte Datenerfassungsgeräte zur DatensammlungAlle Brainware-Geräte von EMOTIV verbinden sich mit der EmotivPRO-Software, die über integrierte LSL-Funktionen zum Senden und Empfangen von Datenströmen verfügtZusätzliche Ressourcen:Code zur Ausführung von LSL mit Emovits Geräten, mit BeispielscriptenNützliche LSL-Demo auf YouTubeSCCN LSL GitHub-Repository für alle zugehörigen BibliothekenGitHub-Repository für eine Sammlung von Submodulen und AppsHyPyP-Analysepipeline für Hyperscanning-Studien

von Roshini Randeniya und Lucas Kleine

Operation:
Sobald es in der Befehlszeile ausgeführt wird, initiiert dieses Skript sofort einen LSL-Stream. Jedes Mal, wenn die 'Enter'-Taste gedrückt wird, sendet es einen Trigger und spielt eine Audiodatei ab."""

import sounddevice as sd
import soundfile as sf
from pylsl import StreamInfo, StreamOutlet

def wait_for_keypress():
print("Drücken Sie ENTER, um die Audio-Wiedergabe zu starten und ein LSL-Marker zu senden.")

while True: # This loop waits for a keyboard input
    input_str = input()  # Wait for input from the terminal
    if input_str == "":  # If the enter key is pressed, proceed
        break

def AudioMarker(audio_file, outlet): # Funktion zum Abspielen von Audio und Senden eines Markers
data, fs = sf.read(audio_file) # Ladet die Audiodatei

print("Playing audio and sending LSL marker...")
marker_val = [1]
outlet.push_sample(marker_val) # Send marker indicating the start of audio playback
sd.play(data, fs) # play the audio
sd.wait()  # Wait until audio is done playing
print("Audio playback finished.")

if name == "main": # HAUPTSCHLEIFE
# LSL-Stream für Marker einrichten
stream_name = 'AudioMarkers'
stream_type = 'Markers'
n_chans = 1
sr = 0 # Setze die Abtastrate auf 0, da Marker unregelmäßig sind
chan_format = 'int32'
marker_id = 'uniqueMarkerID12345'

info = StreamInfo(stream_name, stream_type, n_chans, sr, chan_format, marker_id)
outlet = StreamOutlet(info) # create LSL outlet

# Keep the script running and wait for ENTER key to play audio and send marker
while True:
    wait_for_keypress()
    audio_filepath = "/path/to/your/audio_file.wav"  # replace with correct path to your audio file
    AudioMarker(audio_filepath, outlet)
    # After playing audio and sending a marker, the script goes back to waiting for the next keypress</code></pre><p><em><strong>**By running this file (even before playing the audio), you've initiated an LSL stream through an outlet</strong></em><strong>. Now we'll view that stream in LabRecorder</strong></p><p><strong>STEP 5 - Use LabRecorder to view and save all LSL streams</strong></p><ol><li data-preset-tag="p"><p>Open LabRecorder</p></li><li data-preset-tag="p"><p>Press <em><strong>Update</strong></em>. The available LSL streams should be visible in the stream list<br> • You should be able to see streams from both EmotivPROs (usually called "EmotivDataStream") and the marker stream (called "AudioMarkers")</p></li><li data-preset-tag="p"><p>Click <em><strong>Browse</strong></em> to select a location to store data (and set other parameters)</p></li><li data-preset-tag="p"><p>Select all streams and press <em><strong>Record</strong></em> to start recording</p></li><li data-preset-tag="p"><p>Click Stop when you want to end the recording</p></li></ol><p><br></p><img alt="" src="https://framerusercontent.com/images/HFGuJF9ErVu2Jxrgtqt11tl0No.jpg"><h2><strong>Working with the data</strong></h2><p><strong>LabRecorder outputs an XDF file (Extensible Data Format) that contains data from all the streams. XDF files are structured into, </strong><em><strong>streams</strong></em><strong>, each with a different </strong><em><strong>header</strong></em><strong> that describes what it contains (device name, data type, sampling rate, channels, and more). You can use the below codeblock to open your XDF file and display some basic information.</strong></p><pre data-language="JSX"><code>

Dieses Beispielskript demonstriert einige grundlegende Funktionen, um EEG-Daten zu importieren und zu annotieren, die mit der EmotivPRO-Software gesammelt wurden. Es verwendet MNE, um eine XDF-Datei zu laden, einige grundlegende Metadaten auszudrucken, ein info-Objekt zu erstellen und das Leistungsspektrum darzustellen."""

import pyxdf
import mne
import matplotlib.pyplot as plt
import numpy as np

Pfad zu Ihrer XDF-Datei

data_path = '/path/to/your/xdf_file.xdf'

XDF-Datei laden

streams, fileheader = pyxdf.load_xdf(data_path)
print("XDF-Datei-Header:", fileheader)
print("Anzahl der gefundenen Streams:", len(streams))

for i, stream in enumerate(streams):
print("\nStream", i + 1)
print("Stream-Name:", stream['info']['name'][0])
print("Stream-Typ:", stream['info']['type'][0])
print("Anzahl der Kanäle:", stream['info']['channel_count'][0])
sfreq = float(stream['info']['nominal_srate'][0])
print("Abtastrate:", sfreq)
print("Anzahl der Proben:", len(stream['time_series']))
print("Die ersten 5 Datenpunkte ausdrucken:", stream['time_series'][:5])

channel_names = [chan['label'][0] for chan in stream['info']['desc'][0]['channels'][0]['channel']]
print("Channel Names:", channel_names)
channel_types = 'eeg'

MNE-Info-Objekt erstellen

info = mne.create_info(channel_names, sfreq, channel_types)
data = np.array(stream['time_series']).T # Daten müssen transponiert werden: Kanäle x Proben
raw = mne.io.RawArray(data, info)
raw.plot_psd(fmax=50) # plotten Sie ein einfaches Spektrogramm (Leistungsspektraldichte)Zusätzliche RessourcenLaden Sie dieses Tutorial als Jupyter-Notebook von EMOTIV GitHub herunterSehen Sie sich die LSL Online-Dokumentation an, einschließlich der offiziellen README-Datei auf GitHubSie benötigen ein oder mehrere unterstützte Datenerfassungsgeräte zur DatensammlungAlle Brainware-Geräte von EMOTIV verbinden sich mit der EmotivPRO-Software, die über integrierte LSL-Funktionen zum Senden und Empfangen von Datenströmen verfügtZusätzliche Ressourcen:Code zur Ausführung von LSL mit Emovits Geräten, mit BeispielscriptenNützliche LSL-Demo auf YouTubeSCCN LSL GitHub-Repository für alle zugehörigen BibliothekenGitHub-Repository für eine Sammlung von Submodulen und AppsHyPyP-Analysepipeline für Hyperscanning-Studien

Weiterlesen

Grundlagen der neuronalen Oszillationen

© 2025 EMOTIV, Alle Rechte vorbehalten.

Consent

Ihre Datenschutzentscheidungen (Cookie-Einstellungen)

*Haftungsausschluss – EMOTIV-Produkte sind ausschließlich für Forschungsanwendungen und den persönlichen Gebrauch bestimmt. Unsere Produkte werden nicht als Medizinprodukte verkauft, wie sie in der EU-Richtlinie 93/42/EEC definiert sind. Unsere Produkte sind nicht dafür ausgelegt oder beabsichtigt, zur Diagnose oder Behandlung von Krankheiten verwendet zu werden.

Hinweis zu Übersetzungen: Nicht-englische Versionen dieser Website wurden zu Ihrer Bequemlichkeit mithilfe künstlicher Intelligenz übersetzt. Obwohl wir um Genauigkeit bemüht sind, können automatisierte Übersetzungen Fehler oder Nuancen enthalten, die vom Originaltext abweichen. Für die genauesten Informationen beziehen Sie sich bitte auf die englische Version dieser Seite.

© 2025 EMOTIV, Alle Rechte vorbehalten.

Consent

Ihre Datenschutzentscheidungen (Cookie-Einstellungen)

*Haftungsausschluss – EMOTIV-Produkte sind ausschließlich für Forschungsanwendungen und den persönlichen Gebrauch bestimmt. Unsere Produkte werden nicht als Medizinprodukte verkauft, wie sie in der EU-Richtlinie 93/42/EEC definiert sind. Unsere Produkte sind nicht dafür ausgelegt oder beabsichtigt, zur Diagnose oder Behandlung von Krankheiten verwendet zu werden.

Hinweis zu Übersetzungen: Nicht-englische Versionen dieser Website wurden zu Ihrer Bequemlichkeit mithilfe künstlicher Intelligenz übersetzt. Obwohl wir um Genauigkeit bemüht sind, können automatisierte Übersetzungen Fehler oder Nuancen enthalten, die vom Originaltext abweichen. Für die genauesten Informationen beziehen Sie sich bitte auf die englische Version dieser Seite.

© 2025 EMOTIV, Alle Rechte vorbehalten.

Consent

Ihre Datenschutzentscheidungen (Cookie-Einstellungen)

*Haftungsausschluss – EMOTIV-Produkte sind ausschließlich für Forschungsanwendungen und den persönlichen Gebrauch bestimmt. Unsere Produkte werden nicht als Medizinprodukte verkauft, wie sie in der EU-Richtlinie 93/42/EEC definiert sind. Unsere Produkte sind nicht dafür ausgelegt oder beabsichtigt, zur Diagnose oder Behandlung von Krankheiten verwendet zu werden.

Hinweis zu Übersetzungen: Nicht-englische Versionen dieser Website wurden zu Ihrer Bequemlichkeit mithilfe künstlicher Intelligenz übersetzt. Obwohl wir um Genauigkeit bemüht sind, können automatisierte Übersetzungen Fehler oder Nuancen enthalten, die vom Originaltext abweichen. Für die genauesten Informationen beziehen Sie sich bitte auf die englische Version dieser Seite.