amused


Nameamused JSON
Version 1.0.2 PyPI version JSON
download
home_pageNone
SummaryOpen-source Python library for streaming data from Muse S (Athena) EEG headbands
upload_time2025-08-24 19:03:39
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseMIT
keywords muse eeg ppg fnirs biometrics neuroscience brain-computer-interface bci bluetooth ble biosignals heart-rate meditation sleep-monitoring
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Amused - A Muse S Direct BLE Implementation

**The first open-source BLE protocol implementation for Muse S headsets**

[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

> **Finally!** Direct BLE connection to Muse S without proprietary SDKs. We're quite *amused* that we cracked the protocol nobody else has published online!

## 🎉 The Real Story

We reverse-engineered the BLE communication from scratch to provide researchers with full control over their Muse S devices. 

**Key breakthrough:** The `dc001` command must be sent TWICE to start streaming - a critical detail not in any documentation!

## Features

- **EEG Streaming**: 7 channels at 256 Hz (TP9, AF7, AF8, TP10, FPz, AUX_R, AUX_L)
- **PPG Heart Rate**: Real-time HR and HRV from photoplethysmography sensors  
- **IMU Motion**: 9-axis accelerometer + gyroscope
- **Binary Recording**: 10x more efficient than CSV with replay capability
- **Real-time Visualization**: Multiple visualization options including band powers
- **No SDK Required**: Pure Python with BLE - no proprietary libraries!

## Installation

```bash
pip install amused
```

Or from source:
```bash
git clone https://github.com/nexon33/amused.git
cd amused
pip install -e .
```

### Visualization Dependencies (Optional)

```bash
# For PyQtGraph visualizations
pip install pyqtgraph PyQt5

# For all visualization features
pip install -r requirements-viz.txt
```

## Quick Start

```python
import asyncio
from muse_stream_client import MuseStreamClient
from muse_discovery import find_muse_devices

async def stream():
    # Find Muse devices
    devices = await find_muse_devices()
    if not devices:
        print("No Muse device found!")
        return
    
    device = devices[0]
    print(f"Found: {device.name}")
    
    # Create streaming client
    client = MuseStreamClient(
        save_raw=True,      # Save to binary file
        decode_realtime=True # Decode in real-time
    )
    
    # Stream for 30 seconds
    await client.connect_and_stream(
        device.address,
        duration_seconds=30,
        preset='p1035'  # Full sensor mode
    )
    
    summary = client.get_summary()
    print(f"Collected {summary['packets_received']} packets")

asyncio.run(stream())
```

## Core Components

### `MuseStreamClient`
The main streaming client for real-time data collection:
- Connects to Muse S via BLE
- Streams all sensor data (EEG, PPG, IMU)
- Optional binary recording
- Real-time callbacks for data processing

### `MuseRawStream`
Binary data storage and retrieval:
- Efficient binary format (10x smaller than CSV)
- Fast read/write operations
- Packet-level access with timestamps

### `MuseRealtimeDecoder`
Real-time packet decoding:
- Decodes BLE packets on-the-fly
- Extracts EEG, PPG, IMU data
- Calculates heart rate from PPG
- Minimal latency

### `MuseReplayPlayer`
Replay recorded sessions:
- Play back binary recordings
- Variable speed playback
- Same callback interface as live streaming

## Usage Examples

### 1. Basic Streaming
```python
# See examples/01_basic_streaming.py
from muse_stream_client import MuseStreamClient
from muse_discovery import find_muse_devices

client = MuseStreamClient(
    save_raw=False,  # Don't save, just stream
    decode_realtime=True,
    verbose=True
)

devices = await find_muse_devices()
if devices:
    await client.connect_and_stream(
        devices[0].address,
        duration_seconds=30,
        preset='p1035'
    )
```

### 2. Recording to Binary
```python
# See examples/02_full_sensors.py
client = MuseStreamClient(
    save_raw=True,  # Enable binary saving
    data_dir="muse_data"
)

# Records all sensors to binary file
await client.connect_and_stream(
    device.address,
    duration_seconds=60,
    preset='p1035'
)
```

### 3. Parsing Recorded Data
```python
# See examples/03_parse_data.py
from muse_raw_stream import MuseRawStream
from muse_realtime_decoder import MuseRealtimeDecoder

stream = MuseRawStream("muse_data/recording.bin")
stream.open_read()

decoder = MuseRealtimeDecoder()
for packet in stream.read_packets():
    decoded = decoder.decode(packet.data, packet.timestamp)
    if decoded.eeg:
        print(f"EEG data: {decoded.eeg}")
    if decoded.heart_rate:
        print(f"Heart rate: {decoded.heart_rate:.0f} BPM")
```

### 4. Real-time Callbacks
```python
# See examples/04_stream_with_callbacks.py
def process_eeg(data):
    channels = data['channels']
    # Process EEG data in real-time
    print(f"Got EEG from {len(channels)} channels")

def process_heart_rate(hr):
    print(f"Heart Rate: {hr:.0f} BPM")

client = MuseStreamClient()
client.on_eeg(process_eeg)
client.on_heart_rate(process_heart_rate)

await client.connect_and_stream(device.address)
```

### 5. Visualization Examples

#### Band Power Visualization
```python
# See examples/07_lsl_style_viz.py
# Shows Delta, Theta, Alpha, Beta, Gamma bands
# Stable bar graphs without jumpy waveforms
```

#### Simple Frequency Display
```python
# See examples/09_frequency_display.py
# Just shows dominant frequency (Hz) for each channel
# Clean, large numbers - no graphs
```

#### Heart Rate Monitor
```python
# See examples/06_heart_monitor.py
# Dedicated heart rate display with zones
# Shows current BPM, trend, and history
```

## Protocol Details

The Muse S uses Bluetooth Low Energy (BLE) with a custom protocol:

### Connection Sequence
1. Connect to device
2. Enable notifications on control characteristic
3. Send halt command (`0x02680a`)
4. Set preset (`p1035` for full sensors)
5. Enable sensor notifications
6. Send start command (`dc001`) **TWICE**
7. Stream data

### Presets
- `p21`: Basic EEG only
- `p1034`: Sleep mode preset 1
- `p1035`: Full sensor mode (recommended)

### Packet Types
- `0xDF`: EEG + PPG combined
- `0xF4`: IMU (accelerometer + gyroscope)
- `0xDB`, `0xD9`: Mixed sensor data

## Troubleshooting

### No data received?
- Ensure `dc001` is sent twice (critical!)
- Check Bluetooth is enabled
- Make sure Muse S is in pairing mode
- Try preset `p1035` for full sensor access

### Heart rate not showing?
- Heart rate requires ~2 seconds of PPG data
- Check PPG sensor contact with skin
- Use preset `p1035` which enables PPG

### Qt/Visualization errors?
- Install PyQt5: `pip install PyQt5 pyqtgraph`
- On Windows, the library handles Qt/asyncio conflicts automatically
- Try examples 06 or 09 for simpler visualizations

## Examples Directory

The `examples/` folder contains working examples:

1. `01_basic_streaming.py` - Simple EEG streaming
2. `02_full_sensors.py` - Record all sensors to binary
3. `03_parse_data.py` - Parse binary recordings
4. `04_stream_with_callbacks.py` - Real-time processing
5. `05_save_and_replay.py` - Record and replay sessions
6. `06_heart_monitor.py` - Clean heart rate display
7. `07_lsl_style_viz.py` - LSL-style band power visualization
8. `09_frequency_display.py` - Simple Hz display for each channel

## Contributing

This is the first open implementation! Areas to explore:
- Additional sensor modes
- Machine learning pipelines
- Mobile apps
- Advanced signal processing

## License

MIT License - see LICENSE file

## Citation

If you use Amused in research:
```
@software{amused2025,
  title = {Amused: A Muse S Direct BLE Implementation},
  author = {Adrian Tadeusz Belmans},
  year = {2025},
  url = {https://github.com/nexon33/amused}
}
```

---

**Note**: Research software for educational purposes. Probably not for medical use.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "amused",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "muse, eeg, ppg, fnirs, biometrics, neuroscience, brain-computer-interface, bci, bluetooth, ble, biosignals, heart-rate, meditation, sleep-monitoring",
    "author": null,
    "author_email": "Adrian Tadeusz Belmans <adrian.belmans@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/ef/d9/4476f04535471560ccde88df28c4487eeb42df6fa6df71a9dfafb91c2022/amused-1.0.2.tar.gz",
    "platform": null,
    "description": "# Amused - A Muse S Direct BLE Implementation\r\n\r\n**The first open-source BLE protocol implementation for Muse S headsets**\r\n\r\n[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)\r\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\r\n\r\n> **Finally!** Direct BLE connection to Muse S without proprietary SDKs. We're quite *amused* that we cracked the protocol nobody else has published online!\r\n\r\n## \ud83c\udf89 The Real Story\r\n\r\nWe reverse-engineered the BLE communication from scratch to provide researchers with full control over their Muse S devices. \r\n\r\n**Key breakthrough:** The `dc001` command must be sent TWICE to start streaming - a critical detail not in any documentation!\r\n\r\n## Features\r\n\r\n- **EEG Streaming**: 7 channels at 256 Hz (TP9, AF7, AF8, TP10, FPz, AUX_R, AUX_L)\r\n- **PPG Heart Rate**: Real-time HR and HRV from photoplethysmography sensors  \r\n- **IMU Motion**: 9-axis accelerometer + gyroscope\r\n- **Binary Recording**: 10x more efficient than CSV with replay capability\r\n- **Real-time Visualization**: Multiple visualization options including band powers\r\n- **No SDK Required**: Pure Python with BLE - no proprietary libraries!\r\n\r\n## Installation\r\n\r\n```bash\r\npip install amused\r\n```\r\n\r\nOr from source:\r\n```bash\r\ngit clone https://github.com/nexon33/amused.git\r\ncd amused\r\npip install -e .\r\n```\r\n\r\n### Visualization Dependencies (Optional)\r\n\r\n```bash\r\n# For PyQtGraph visualizations\r\npip install pyqtgraph PyQt5\r\n\r\n# For all visualization features\r\npip install -r requirements-viz.txt\r\n```\r\n\r\n## Quick Start\r\n\r\n```python\r\nimport asyncio\r\nfrom muse_stream_client import MuseStreamClient\r\nfrom muse_discovery import find_muse_devices\r\n\r\nasync def stream():\r\n    # Find Muse devices\r\n    devices = await find_muse_devices()\r\n    if not devices:\r\n        print(\"No Muse device found!\")\r\n        return\r\n    \r\n    device = devices[0]\r\n    print(f\"Found: {device.name}\")\r\n    \r\n    # Create streaming client\r\n    client = MuseStreamClient(\r\n        save_raw=True,      # Save to binary file\r\n        decode_realtime=True # Decode in real-time\r\n    )\r\n    \r\n    # Stream for 30 seconds\r\n    await client.connect_and_stream(\r\n        device.address,\r\n        duration_seconds=30,\r\n        preset='p1035'  # Full sensor mode\r\n    )\r\n    \r\n    summary = client.get_summary()\r\n    print(f\"Collected {summary['packets_received']} packets\")\r\n\r\nasyncio.run(stream())\r\n```\r\n\r\n## Core Components\r\n\r\n### `MuseStreamClient`\r\nThe main streaming client for real-time data collection:\r\n- Connects to Muse S via BLE\r\n- Streams all sensor data (EEG, PPG, IMU)\r\n- Optional binary recording\r\n- Real-time callbacks for data processing\r\n\r\n### `MuseRawStream`\r\nBinary data storage and retrieval:\r\n- Efficient binary format (10x smaller than CSV)\r\n- Fast read/write operations\r\n- Packet-level access with timestamps\r\n\r\n### `MuseRealtimeDecoder`\r\nReal-time packet decoding:\r\n- Decodes BLE packets on-the-fly\r\n- Extracts EEG, PPG, IMU data\r\n- Calculates heart rate from PPG\r\n- Minimal latency\r\n\r\n### `MuseReplayPlayer`\r\nReplay recorded sessions:\r\n- Play back binary recordings\r\n- Variable speed playback\r\n- Same callback interface as live streaming\r\n\r\n## Usage Examples\r\n\r\n### 1. Basic Streaming\r\n```python\r\n# See examples/01_basic_streaming.py\r\nfrom muse_stream_client import MuseStreamClient\r\nfrom muse_discovery import find_muse_devices\r\n\r\nclient = MuseStreamClient(\r\n    save_raw=False,  # Don't save, just stream\r\n    decode_realtime=True,\r\n    verbose=True\r\n)\r\n\r\ndevices = await find_muse_devices()\r\nif devices:\r\n    await client.connect_and_stream(\r\n        devices[0].address,\r\n        duration_seconds=30,\r\n        preset='p1035'\r\n    )\r\n```\r\n\r\n### 2. Recording to Binary\r\n```python\r\n# See examples/02_full_sensors.py\r\nclient = MuseStreamClient(\r\n    save_raw=True,  # Enable binary saving\r\n    data_dir=\"muse_data\"\r\n)\r\n\r\n# Records all sensors to binary file\r\nawait client.connect_and_stream(\r\n    device.address,\r\n    duration_seconds=60,\r\n    preset='p1035'\r\n)\r\n```\r\n\r\n### 3. Parsing Recorded Data\r\n```python\r\n# See examples/03_parse_data.py\r\nfrom muse_raw_stream import MuseRawStream\r\nfrom muse_realtime_decoder import MuseRealtimeDecoder\r\n\r\nstream = MuseRawStream(\"muse_data/recording.bin\")\r\nstream.open_read()\r\n\r\ndecoder = MuseRealtimeDecoder()\r\nfor packet in stream.read_packets():\r\n    decoded = decoder.decode(packet.data, packet.timestamp)\r\n    if decoded.eeg:\r\n        print(f\"EEG data: {decoded.eeg}\")\r\n    if decoded.heart_rate:\r\n        print(f\"Heart rate: {decoded.heart_rate:.0f} BPM\")\r\n```\r\n\r\n### 4. Real-time Callbacks\r\n```python\r\n# See examples/04_stream_with_callbacks.py\r\ndef process_eeg(data):\r\n    channels = data['channels']\r\n    # Process EEG data in real-time\r\n    print(f\"Got EEG from {len(channels)} channels\")\r\n\r\ndef process_heart_rate(hr):\r\n    print(f\"Heart Rate: {hr:.0f} BPM\")\r\n\r\nclient = MuseStreamClient()\r\nclient.on_eeg(process_eeg)\r\nclient.on_heart_rate(process_heart_rate)\r\n\r\nawait client.connect_and_stream(device.address)\r\n```\r\n\r\n### 5. Visualization Examples\r\n\r\n#### Band Power Visualization\r\n```python\r\n# See examples/07_lsl_style_viz.py\r\n# Shows Delta, Theta, Alpha, Beta, Gamma bands\r\n# Stable bar graphs without jumpy waveforms\r\n```\r\n\r\n#### Simple Frequency Display\r\n```python\r\n# See examples/09_frequency_display.py\r\n# Just shows dominant frequency (Hz) for each channel\r\n# Clean, large numbers - no graphs\r\n```\r\n\r\n#### Heart Rate Monitor\r\n```python\r\n# See examples/06_heart_monitor.py\r\n# Dedicated heart rate display with zones\r\n# Shows current BPM, trend, and history\r\n```\r\n\r\n## Protocol Details\r\n\r\nThe Muse S uses Bluetooth Low Energy (BLE) with a custom protocol:\r\n\r\n### Connection Sequence\r\n1. Connect to device\r\n2. Enable notifications on control characteristic\r\n3. Send halt command (`0x02680a`)\r\n4. Set preset (`p1035` for full sensors)\r\n5. Enable sensor notifications\r\n6. Send start command (`dc001`) **TWICE**\r\n7. Stream data\r\n\r\n### Presets\r\n- `p21`: Basic EEG only\r\n- `p1034`: Sleep mode preset 1\r\n- `p1035`: Full sensor mode (recommended)\r\n\r\n### Packet Types\r\n- `0xDF`: EEG + PPG combined\r\n- `0xF4`: IMU (accelerometer + gyroscope)\r\n- `0xDB`, `0xD9`: Mixed sensor data\r\n\r\n## Troubleshooting\r\n\r\n### No data received?\r\n- Ensure `dc001` is sent twice (critical!)\r\n- Check Bluetooth is enabled\r\n- Make sure Muse S is in pairing mode\r\n- Try preset `p1035` for full sensor access\r\n\r\n### Heart rate not showing?\r\n- Heart rate requires ~2 seconds of PPG data\r\n- Check PPG sensor contact with skin\r\n- Use preset `p1035` which enables PPG\r\n\r\n### Qt/Visualization errors?\r\n- Install PyQt5: `pip install PyQt5 pyqtgraph`\r\n- On Windows, the library handles Qt/asyncio conflicts automatically\r\n- Try examples 06 or 09 for simpler visualizations\r\n\r\n## Examples Directory\r\n\r\nThe `examples/` folder contains working examples:\r\n\r\n1. `01_basic_streaming.py` - Simple EEG streaming\r\n2. `02_full_sensors.py` - Record all sensors to binary\r\n3. `03_parse_data.py` - Parse binary recordings\r\n4. `04_stream_with_callbacks.py` - Real-time processing\r\n5. `05_save_and_replay.py` - Record and replay sessions\r\n6. `06_heart_monitor.py` - Clean heart rate display\r\n7. `07_lsl_style_viz.py` - LSL-style band power visualization\r\n8. `09_frequency_display.py` - Simple Hz display for each channel\r\n\r\n## Contributing\r\n\r\nThis is the first open implementation! Areas to explore:\r\n- Additional sensor modes\r\n- Machine learning pipelines\r\n- Mobile apps\r\n- Advanced signal processing\r\n\r\n## License\r\n\r\nMIT License - see LICENSE file\r\n\r\n## Citation\r\n\r\nIf you use Amused in research:\r\n```\r\n@software{amused2025,\r\n  title = {Amused: A Muse S Direct BLE Implementation},\r\n  author = {Adrian Tadeusz Belmans},\r\n  year = {2025},\r\n  url = {https://github.com/nexon33/amused}\r\n}\r\n```\r\n\r\n---\r\n\r\n**Note**: Research software for educational purposes. Probably not for medical use.\r\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Open-source Python library for streaming data from Muse S (Athena) EEG headbands",
    "version": "1.0.2",
    "project_urls": {
        "Documentation": "https://github.com/nexon33/amused#readme",
        "Homepage": "https://github.com/nexon33/amused",
        "Issues": "https://github.com/nexon33/amused/issues",
        "Repository": "https://github.com/nexon33/amused"
    },
    "split_keywords": [
        "muse",
        " eeg",
        " ppg",
        " fnirs",
        " biometrics",
        " neuroscience",
        " brain-computer-interface",
        " bci",
        " bluetooth",
        " ble",
        " biosignals",
        " heart-rate",
        " meditation",
        " sleep-monitoring"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "1dad99546064613197b1844fe7caee77bac308c233ead9f611455375fea09541",
                "md5": "e4efeb804be95ebdf9ed82f2ea3afd74",
                "sha256": "5bfb1df799fb61bad9ddd19bf92d297e70e09d8baaa4419a0c8e7b33cbd54f72"
            },
            "downloads": -1,
            "filename": "amused-1.0.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "e4efeb804be95ebdf9ed82f2ea3afd74",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 64590,
            "upload_time": "2025-08-24T19:03:38",
            "upload_time_iso_8601": "2025-08-24T19:03:38.216970Z",
            "url": "https://files.pythonhosted.org/packages/1d/ad/99546064613197b1844fe7caee77bac308c233ead9f611455375fea09541/amused-1.0.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "efd94476f04535471560ccde88df28c4487eeb42df6fa6df71a9dfafb91c2022",
                "md5": "a4f9ef2c7b8d058c63609dd36159fdff",
                "sha256": "6e8bee09f76430f9a9a971433b1feb68f53bf22a71a248774f72175d97869135"
            },
            "downloads": -1,
            "filename": "amused-1.0.2.tar.gz",
            "has_sig": false,
            "md5_digest": "a4f9ef2c7b8d058c63609dd36159fdff",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 65992,
            "upload_time": "2025-08-24T19:03:39",
            "upload_time_iso_8601": "2025-08-24T19:03:39.546848Z",
            "url": "https://files.pythonhosted.org/packages/ef/d9/4476f04535471560ccde88df28c4487eeb42df6fa6df71a9dfafb91c2022/amused-1.0.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-24 19:03:39",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "nexon33",
    "github_project": "amused#readme",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "amused"
}
        
Elapsed time: 1.29583s