Capa de Streaming de Laboratorio (LSL) para sincronizar múltiples flujos de datos

Roshini Randeniya

1 oct 2025

Compartir:

por Roshini Randeniya y Lucas Kleine

Operación:
Una vez ejecutado en la línea de comandos, este script inicia inmediatamente un flujo LSL. Cada vez que se presiona la tecla 'Enter', envía un desencadenador y reproduce un archivo de audio."""

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

def wait_for_keypress():
print("Presiona ENTER para comenzar la reproducción de audio y enviar un marcador LSL.")

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): # función para reproducir audio y enviar marcador
data, fs = sf.read(audio_file) # Cargar el archivo de audio

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": # BUCLE PRINCIPAL
# Configurar flujo LSL para marcadores
stream_name = 'AudioMarkers'
stream_type = 'Markers'
n_chans = 1
sr = 0 # Establecer la frecuencia de muestreo en 0 porque los marcadores son irregulares
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>

Este script de ejemplo demuestra algunas funciones básicas para importar y anotar datos de EEG recopilados del software EmotivPRO. Utiliza MNE para cargar un archivo XDF, imprimir algunos metadatos básicos, crear un objeto info y trazar el espectro de potencia."""

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

Ruta a su archivo XDF

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

Cargar el archivo XDF

streams, fileheader = pyxdf.load_xdf(data_path)
print("Encabezado del archivo XDF:", fileheader)
print("Número de flujos encontrados:", len(streams))

for i, stream in enumerate(streams):
print("\nFlujo", i + 1)
print("Nombre del flujo:", stream['info']['name'][0])
print("Tipo de flujo:", stream['info']['type'][0])
print("Número de canales:", stream['info']['channel_count'][0])
sfreq = float(stream['info']['nominal_srate'][0])
print("Frecuencia de muestreo:", sfreq)
print("Número de muestras:", len(stream['time_series']))
print("Imprimir los primeros 5 puntos de datos:", 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'

Crear objeto de información de MNE

info = mne.create_info(channel_names, sfreq, channel_types)
data = np.array(stream['time_series']).T # Los datos deben ser transpuestos: canales x muestras
raw = mne.io.RawArray(data, info)
raw.plot_psd(fmax=50) # trazar un espectrograma simple (densidad espectral de potencia) Recursos adicionales Descargue este tutorial como un cuaderno Jupyter desde EMOTIV GitHub Consulte la documentación en línea de LSL, incluido el archivo README oficial en GitHub Necesitará uno o más dispositivos de adquisición de datos compatibles para recopilar datos Todos los dispositivos de brainware de EMOTIV se conectan al software EmotivPRO, que tiene capacidades integradas de LSL para enviar y recibir flujos de datos Recursos adicionales: Código para ejecutar LSL utilizando los dispositivos de Emotiv, con scripts de ejemplo Útil demostración de LSL en YouTube Repositorio de GitHub de SCCN LSL para todas las bibliotecas asociadas Repositorio de GitHub para una colección de submódulos y aplicaciones Canal de análisis HyPyP para estudios de hiperescanización

por Roshini Randeniya y Lucas Kleine

Operación:
Una vez ejecutado en la línea de comandos, este script inicia inmediatamente un flujo LSL. Cada vez que se presiona la tecla 'Enter', envía un desencadenador y reproduce un archivo de audio."""

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

def wait_for_keypress():
print("Presiona ENTER para comenzar la reproducción de audio y enviar un marcador LSL.")

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): # función para reproducir audio y enviar marcador
data, fs = sf.read(audio_file) # Cargar el archivo de audio

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": # BUCLE PRINCIPAL
# Configurar flujo LSL para marcadores
stream_name = 'AudioMarkers'
stream_type = 'Markers'
n_chans = 1
sr = 0 # Establecer la frecuencia de muestreo en 0 porque los marcadores son irregulares
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>

Este script de ejemplo demuestra algunas funciones básicas para importar y anotar datos de EEG recopilados del software EmotivPRO. Utiliza MNE para cargar un archivo XDF, imprimir algunos metadatos básicos, crear un objeto info y trazar el espectro de potencia."""

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

Ruta a su archivo XDF

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

Cargar el archivo XDF

streams, fileheader = pyxdf.load_xdf(data_path)
print("Encabezado del archivo XDF:", fileheader)
print("Número de flujos encontrados:", len(streams))

for i, stream in enumerate(streams):
print("\nFlujo", i + 1)
print("Nombre del flujo:", stream['info']['name'][0])
print("Tipo de flujo:", stream['info']['type'][0])
print("Número de canales:", stream['info']['channel_count'][0])
sfreq = float(stream['info']['nominal_srate'][0])
print("Frecuencia de muestreo:", sfreq)
print("Número de muestras:", len(stream['time_series']))
print("Imprimir los primeros 5 puntos de datos:", 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'

Crear objeto de información de MNE

info = mne.create_info(channel_names, sfreq, channel_types)
data = np.array(stream['time_series']).T # Los datos deben ser transpuestos: canales x muestras
raw = mne.io.RawArray(data, info)
raw.plot_psd(fmax=50) # trazar un espectrograma simple (densidad espectral de potencia) Recursos adicionales Descargue este tutorial como un cuaderno Jupyter desde EMOTIV GitHub Consulte la documentación en línea de LSL, incluido el archivo README oficial en GitHub Necesitará uno o más dispositivos de adquisición de datos compatibles para recopilar datos Todos los dispositivos de brainware de EMOTIV se conectan al software EmotivPRO, que tiene capacidades integradas de LSL para enviar y recibir flujos de datos Recursos adicionales: Código para ejecutar LSL utilizando los dispositivos de Emotiv, con scripts de ejemplo Útil demostración de LSL en YouTube Repositorio de GitHub de SCCN LSL para todas las bibliotecas asociadas Repositorio de GitHub para una colección de submódulos y aplicaciones Canal de análisis HyPyP para estudios de hiperescanización

por Roshini Randeniya y Lucas Kleine

Operación:
Una vez ejecutado en la línea de comandos, este script inicia inmediatamente un flujo LSL. Cada vez que se presiona la tecla 'Enter', envía un desencadenador y reproduce un archivo de audio."""

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

def wait_for_keypress():
print("Presiona ENTER para comenzar la reproducción de audio y enviar un marcador LSL.")

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): # función para reproducir audio y enviar marcador
data, fs = sf.read(audio_file) # Cargar el archivo de audio

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": # BUCLE PRINCIPAL
# Configurar flujo LSL para marcadores
stream_name = 'AudioMarkers'
stream_type = 'Markers'
n_chans = 1
sr = 0 # Establecer la frecuencia de muestreo en 0 porque los marcadores son irregulares
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>

Este script de ejemplo demuestra algunas funciones básicas para importar y anotar datos de EEG recopilados del software EmotivPRO. Utiliza MNE para cargar un archivo XDF, imprimir algunos metadatos básicos, crear un objeto info y trazar el espectro de potencia."""

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

Ruta a su archivo XDF

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

Cargar el archivo XDF

streams, fileheader = pyxdf.load_xdf(data_path)
print("Encabezado del archivo XDF:", fileheader)
print("Número de flujos encontrados:", len(streams))

for i, stream in enumerate(streams):
print("\nFlujo", i + 1)
print("Nombre del flujo:", stream['info']['name'][0])
print("Tipo de flujo:", stream['info']['type'][0])
print("Número de canales:", stream['info']['channel_count'][0])
sfreq = float(stream['info']['nominal_srate'][0])
print("Frecuencia de muestreo:", sfreq)
print("Número de muestras:", len(stream['time_series']))
print("Imprimir los primeros 5 puntos de datos:", 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'

Crear objeto de información de MNE

info = mne.create_info(channel_names, sfreq, channel_types)
data = np.array(stream['time_series']).T # Los datos deben ser transpuestos: canales x muestras
raw = mne.io.RawArray(data, info)
raw.plot_psd(fmax=50) # trazar un espectrograma simple (densidad espectral de potencia) Recursos adicionales Descargue este tutorial como un cuaderno Jupyter desde EMOTIV GitHub Consulte la documentación en línea de LSL, incluido el archivo README oficial en GitHub Necesitará uno o más dispositivos de adquisición de datos compatibles para recopilar datos Todos los dispositivos de brainware de EMOTIV se conectan al software EmotivPRO, que tiene capacidades integradas de LSL para enviar y recibir flujos de datos Recursos adicionales: Código para ejecutar LSL utilizando los dispositivos de Emotiv, con scripts de ejemplo Útil demostración de LSL en YouTube Repositorio de GitHub de SCCN LSL para todas las bibliotecas asociadas Repositorio de GitHub para una colección de submódulos y aplicaciones Canal de análisis HyPyP para estudios de hiperescanización

Continúa leyendo

Fundamentos de las Oscilaciones Neurales

© 2025 EMOTIV, Todos los derechos reservados.

Consent

Tus opciones de privacidad (Configuración de cookies)

*Descargo de responsabilidad – Los productos de EMOTIV están destinados a ser utilizados solo para aplicaciones de investigación y uso personal. Nuestros productos no se venden como Dispositivos Médicos según lo definido en la directiva de la UE 93/42/EEC. Nuestros productos no están diseñados ni destinados a ser utilizados para el diagnóstico o tratamiento de enfermedades.

Nota sobre las traducciones: Las versiones en idiomas distintos del inglés de este sitio web han sido traducidas para su conveniencia utilizando inteligencia artificial. Si bien nos esforzamos por la precisión, las traducciones automáticas pueden contener errores o matices que difieren del texto original. Para la información más precisa, consulte la versión en inglés de este sitio.

© 2025 EMOTIV, Todos los derechos reservados.

Consent

Tus opciones de privacidad (Configuración de cookies)

*Descargo de responsabilidad – Los productos de EMOTIV están destinados a ser utilizados solo para aplicaciones de investigación y uso personal. Nuestros productos no se venden como Dispositivos Médicos según lo definido en la directiva de la UE 93/42/EEC. Nuestros productos no están diseñados ni destinados a ser utilizados para el diagnóstico o tratamiento de enfermedades.

Nota sobre las traducciones: Las versiones en idiomas distintos del inglés de este sitio web han sido traducidas para su conveniencia utilizando inteligencia artificial. Si bien nos esforzamos por la precisión, las traducciones automáticas pueden contener errores o matices que difieren del texto original. Para la información más precisa, consulte la versión en inglés de este sitio.

© 2025 EMOTIV, Todos los derechos reservados.

Consent

Tus opciones de privacidad (Configuración de cookies)

*Descargo de responsabilidad – Los productos de EMOTIV están destinados a ser utilizados solo para aplicaciones de investigación y uso personal. Nuestros productos no se venden como Dispositivos Médicos según lo definido en la directiva de la UE 93/42/EEC. Nuestros productos no están diseñados ni destinados a ser utilizados para el diagnóstico o tratamiento de enfermedades.

Nota sobre las traducciones: Las versiones en idiomas distintos del inglés de este sitio web han sido traducidas para su conveniencia utilizando inteligencia artificial. Si bien nos esforzamos por la precisión, las traducciones automáticas pueden contener errores o matices que difieren del texto original. Para la información más precisa, consulte la versión en inglés de este sitio.