Official PyTorch implementation of Channel-Oriented Design for EEG-to-Music Reconstruction
This repository implements a channel-oriented framework for reconstructing semantically faithful music from non-invasive EEG signals. The central insight is that early channel mixing destroys weak but discriminative EEG signals; instead, we preserve electrode-level structure throughout representation learning and defer cross-channel integration to later transformer stages.
The pipeline has three stages:
| Component | Description |
|---|---|
| Channel-wise tokenization | Each of the 125 electrodes is treated as an explicit token; temporal patches are embedded per channel. |
| Channel-wise multi-view self-distillation | DINO-style pretraining with global/local temporal crops and random channel subsets. |
| Channel-wise data augmentation | Structured channel dropout during alignment for robustness to missing electrodes and noise. |
| Method | CLAP ↑ | 50-way ID ↑ | 14-way ID ↑ | 10-way genre ↑ |
|---|---|---|---|---|
| EEG2Mel | 0.588 | 0.259 | 0.478 | 0.132 |
| LaBraM | 0.657 | 0.380 | 0.681 | 0.162 |
| CBraMod | 0.641 | 0.402 | 0.690 | 0.169 |
| Ours | 0.683 | 0.487 | 0.692 | 0.203 |
git clone https://github.com/jqin4749/EEG-to-Music.git
cd EEG-to-Music
conda env create -f env.yaml
conda activate eegmusic
Follow the AudioLDM repository to install the audioldm package. AudioLDM is released under the CC BY-NC-SA 4.0 license.
git clone https://github.com/haoheliu/AudioLDM.git
cd AudioLDM
pip install -e .
The package is also installed in editable mode via env.yaml (-e . for this repo).
Training scripts log to Weights & Biases. Log in before running:
wandb login
We use the Naturalistic Music EEG Dataset in two variants:
Both datasets provide 125-channel EEG at 150 Hz (downsampled to 125 Hz in this code), band-pass filtered (0.3–50 Hz), with per-channel z-score normalization.
Set data_path in the config files to the parent directory containing both splits:
NMED/
├── H/
│ ├── music/ # .wav files (e.g., ainvayi_ainvayi.wav)
│ └── data_processed/ # .mat files with EEG recordings
└── T/
├── music/
└── data_processed/
Update data_path and working_dir in the YAML configs under configs/ before training.
The full pipeline consists of pretraining, alignment, feature extraction, reconstruction, and evaluation.
Pretrain the channel-oriented EEG encoder on unlabeled EEG segments using DINO-style multi-view self-distillation.
python scripts/pretrain.py --config configs/pretrain.yaml
Key settings in configs/pretrain.yaml:
Checkpoints are saved to {working_dir}/results/eeg_music_pretrain/{timestamp}/pretrained/.
Fine-tune the pretrained encoder with paired EEG–music contrastive alignment.
python scripts/align.py --config configs/align.yaml
Set pretrain_model_path in configs/align.yaml to the checkpoint from Step 1. Key settings:
Checkpoints are saved to {working_dir}/results/eeg_music_align/{timestamp}/pretrained/.
Extract aligned EEG features and fit a ridge regression mapping to the CLAP embedding space. Edit paths in the script before running:
python scripts/generate_eeg_features.py
Condition AudioLDM on ridge-adapted EEG embeddings to generate audio waveforms. Edit paths in the script before running:
python scripts/recon_music.py
AudioLDM uses 100 diffusion steps by default. Generated samples are written as .wav files.
Embedding-level metrics (50-way / 14-way identification):
python scripts/eval_embspace.py
Audio-level metrics (CLAP score, SSIM, PSNR, 10-way genre classification):
python scripts/eval_results.py
Upper-bound reference (ground-truth audio through the same pipeline):
python scripts/eval_embspace_upperbound.py
Note: Evaluation and reconstruction scripts contain hardcoded data and output paths. Update them to match your local setup before running.
Direct EEG-to-mel-spectrogram regression baseline.
# Train
python scripts/eeg2mel_train.py --config configs/eeg2mel.yaml
# Generate audio from predicted mel spectrograms
python scripts/eeg2mel_gen.py
LaBraM foundation model baseline with the shared alignment pipeline.
# Train neural tokenizer (optional, for from-scratch LaBraM)
python scripts/labram_tokenizer_train.py --config configs/labram_tokenizer.yaml
# Pretrain LaBraM on NMED
python scripts/labram_pretrain.py --config configs/labram_pretrain.yaml
# Align with LaBraM encoder (set use_labram_model: true in align.yaml)
python scripts/align.py --config configs/align.yaml
├── configs/ # Training and alignment hyperparameters
│ ├── pretrain.yaml # Self-distillation pretraining
│ ├── align.yaml # EEG–music contrastive alignment
│ ├── eeg2mel.yaml # EEG2Mel baseline
│ ├── labram_pretrain.yaml # LaBraM pretraining
│ └── labram_tokenizer.yaml # LaBraM tokenizer
├── scripts/
│ ├── pretrain.py # Channel-wise self-distillation
│ ├── align.py # CLIP-style alignment
│ ├── generate_eeg_features.py
│ ├── recon_music.py # AudioLDM reconstruction
│ ├── eval_embspace.py # Embedding-level evaluation
│ ├── eval_results.py # Audio-level evaluation
│ ├── eeg2mel_train.py # EEG2Mel baseline training
│ ├── eeg2mel_gen.py # EEG2Mel audio generation
│ ├── labram_pretrain.py # LaBraM baseline
│ └── numerical_checks.py # Theoretical masking analysis
└── src/eegmusic/
├── datasets/nmed.py # NMED-T / NMED-H data loader
├── models/
│ ├── eeg_encoder.py # Channel-oriented EEG encoder
│ ├── transformer.py # Transformer backbone
│ ├── whisper.py # CLAP / Whisper audio encoders
│ ├── eeg2mel.py # EEG2Mel baseline model
│ └── labram.py # LaBraM baseline adapter
└── utils/ # Masking, augmentation, misc helpers
If you find this work useful, please cite:
@article{qing2026channel,
title={Channel-Oriented Design for EEG-to-Music Reconstruction},
author={Qing, Jiaxin and Lu, Junwei and Li, Lexin},
journal={Arxiv},
year={2026}
}
This code is released for research purposes. AudioLDM components are subject to the CC BY-NC-SA 4.0 license. Please refer to the respective dataset licenses for NMED-T and NMED-H.
2 commits
Python
100.0%
Official PyTorch implementation of Channel-Oriented Design for EEG-to-Music Reconstruction
This repository implements a channel-oriented framework for reconstructing semantically faithful music from non-invasive EEG signals. The central insight is that early channel mixing destroys weak but discriminative EEG signals; instead, we preserve electrode-level structure throughout representation learning and defer cross-channel integration to later transformer stages.
The pipeline has three stages:
| Component | Description |
|---|---|
| Channel-wise tokenization | Each of the 125 electrodes is treated as an explicit token; temporal patches are embedded per channel. |
| Channel-wise multi-view self-distillation | DINO-style pretraining with global/local temporal crops and random channel subsets. |
| Channel-wise data augmentation | Structured channel dropout during alignment for robustness to missing electrodes and noise. |
| Method | CLAP ↑ | 50-way ID ↑ | 14-way ID ↑ | 10-way genre ↑ |
|---|---|---|---|---|
| EEG2Mel | 0.588 | 0.259 | 0.478 | 0.132 |
| LaBraM | 0.657 | 0.380 | 0.681 | 0.162 |
| CBraMod | 0.641 | 0.402 | 0.690 | 0.169 |
| Ours | 0.683 | 0.487 | 0.692 | 0.203 |
git clone https://github.com/jqin4749/EEG-to-Music.git
cd EEG-to-Music
conda env create -f env.yaml
conda activate eegmusic
Follow the AudioLDM repository to install the audioldm package. AudioLDM is released under the CC BY-NC-SA 4.0 license.
git clone https://github.com/haoheliu/AudioLDM.git
cd AudioLDM
pip install -e .
The package is also installed in editable mode via env.yaml (-e . for this repo).
Training scripts log to Weights & Biases. Log in before running:
wandb login
We use the Naturalistic Music EEG Dataset in two variants:
Both datasets provide 125-channel EEG at 150 Hz (downsampled to 125 Hz in this code), band-pass filtered (0.3–50 Hz), with per-channel z-score normalization.
Set data_path in the config files to the parent directory containing both splits:
NMED/
├── H/
│ ├── music/ # .wav files (e.g., ainvayi_ainvayi.wav)
│ └── data_processed/ # .mat files with EEG recordings
└── T/
├── music/
└── data_processed/
Update data_path and working_dir in the YAML configs under configs/ before training.
The full pipeline consists of pretraining, alignment, feature extraction, reconstruction, and evaluation.
Pretrain the channel-oriented EEG encoder on unlabeled EEG segments using DINO-style multi-view self-distillation.
python scripts/pretrain.py --config configs/pretrain.yaml
Key settings in configs/pretrain.yaml:
Checkpoints are saved to {working_dir}/results/eeg_music_pretrain/{timestamp}/pretrained/.
Fine-tune the pretrained encoder with paired EEG–music contrastive alignment.
python scripts/align.py --config configs/align.yaml
Set pretrain_model_path in configs/align.yaml to the checkpoint from Step 1. Key settings:
Checkpoints are saved to {working_dir}/results/eeg_music_align/{timestamp}/pretrained/.
Extract aligned EEG features and fit a ridge regression mapping to the CLAP embedding space. Edit paths in the script before running:
python scripts/generate_eeg_features.py
Condition AudioLDM on ridge-adapted EEG embeddings to generate audio waveforms. Edit paths in the script before running:
python scripts/recon_music.py
AudioLDM uses 100 diffusion steps by default. Generated samples are written as .wav files.
Embedding-level metrics (50-way / 14-way identification):
python scripts/eval_embspace.py
Audio-level metrics (CLAP score, SSIM, PSNR, 10-way genre classification):
python scripts/eval_results.py
Upper-bound reference (ground-truth audio through the same pipeline):
python scripts/eval_embspace_upperbound.py
Note: Evaluation and reconstruction scripts contain hardcoded data and output paths. Update them to match your local setup before running.
Direct EEG-to-mel-spectrogram regression baseline.
# Train
python scripts/eeg2mel_train.py --config configs/eeg2mel.yaml
# Generate audio from predicted mel spectrograms
python scripts/eeg2mel_gen.py
LaBraM foundation model baseline with the shared alignment pipeline.
# Train neural tokenizer (optional, for from-scratch LaBraM)
python scripts/labram_tokenizer_train.py --config configs/labram_tokenizer.yaml
# Pretrain LaBraM on NMED
python scripts/labram_pretrain.py --config configs/labram_pretrain.yaml
# Align with LaBraM encoder (set use_labram_model: true in align.yaml)
python scripts/align.py --config configs/align.yaml
├── configs/ # Training and alignment hyperparameters
│ ├── pretrain.yaml # Self-distillation pretraining
│ ├── align.yaml # EEG–music contrastive alignment
│ ├── eeg2mel.yaml # EEG2Mel baseline
│ ├── labram_pretrain.yaml # LaBraM pretraining
│ └── labram_tokenizer.yaml # LaBraM tokenizer
├── scripts/
│ ├── pretrain.py # Channel-wise self-distillation
│ ├── align.py # CLIP-style alignment
│ ├── generate_eeg_features.py
│ ├── recon_music.py # AudioLDM reconstruction
│ ├── eval_embspace.py # Embedding-level evaluation
│ ├── eval_results.py # Audio-level evaluation
│ ├── eeg2mel_train.py # EEG2Mel baseline training
│ ├── eeg2mel_gen.py # EEG2Mel audio generation
│ ├── labram_pretrain.py # LaBraM baseline
│ └── numerical_checks.py # Theoretical masking analysis
└── src/eegmusic/
├── datasets/nmed.py # NMED-T / NMED-H data loader
├── models/
│ ├── eeg_encoder.py # Channel-oriented EEG encoder
│ ├── transformer.py # Transformer backbone
│ ├── whisper.py # CLAP / Whisper audio encoders
│ ├── eeg2mel.py # EEG2Mel baseline model
│ └── labram.py # LaBraM baseline adapter
└── utils/ # Masking, augmentation, misc helpers
If you find this work useful, please cite:
@article{qing2026channel,
title={Channel-Oriented Design for EEG-to-Music Reconstruction},
author={Qing, Jiaxin and Lu, Junwei and Li, Lexin},
journal={Arxiv},
year={2026}
}
This code is released for research purposes. AudioLDM components are subject to the CC BY-NC-SA 4.0 license. Please refer to the respective dataset licenses for NMED-T and NMED-H.
2 commits
Python
100.0%