iamtatsuki05
commited on
Commit
•
0338d23
1
Parent(s):
f7591ac
Synced repo using 'sync_with_huggingface' Github Action
Browse files- .dockerignore +9 -0
- .pre-commit-config.yaml +13 -0
- Dockerfile +66 -0
- Makefile +0 -0
- compose.yaml +29 -0
- docker/cpu/Dockerfile +63 -0
- env.sample +0 -0
- images/app_sample.png +0 -0
- notebooks/helloworld.ipynb +51 -0
- poetry.lock +0 -0
- pyproject.toml +57 -0
- scripts/main.py +2 -0
- src/__init__.py +0 -0
- src/app.py +103 -0
- src/brainwave/__init__.py +0 -0
- src/brainwave/common/__init__.py +0 -0
- src/brainwave/common/utils/__init__.py +0 -0
- src/brainwave/config/__init__.py +0 -0
- src/brainwave/config/app.py +21 -0
- src/brainwave/env.py +3 -0
- src/brainwave/main.py +6 -0
- src/brainwave/utils/__init__.py +0 -0
- src/brainwave/utils/binaural_beats.py +20 -0
- tests/brainwave/__init__.py +0 -0
.dockerignore
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
html/*
|
2 |
+
.DS_Store
|
3 |
+
|
4 |
+
.venv
|
5 |
+
*.swp
|
6 |
+
.mypy_cache
|
7 |
+
.pytest_cache
|
8 |
+
.ipynb_checkpoints
|
9 |
+
__pycache__
|
.pre-commit-config.yaml
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
repos:
|
2 |
+
- repo: https://github.com/psf/black
|
3 |
+
rev: 22.12.0
|
4 |
+
hooks:
|
5 |
+
- id: black
|
6 |
+
types: [python]
|
7 |
+
language_version: python3.10.11
|
8 |
+
- repo: https://github.com/PyCQA/isort
|
9 |
+
rev: 5.12.0
|
10 |
+
hooks:
|
11 |
+
- id: isort
|
12 |
+
types: [python]
|
13 |
+
language_version: python3.10.11
|
Dockerfile
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
FROM ubuntu:22.04 AS base
|
2 |
+
|
3 |
+
ARG PYTHON_VERSION=3.10
|
4 |
+
|
5 |
+
ENV DEBIAN_FRONTEND=noninteractive
|
6 |
+
ENV WORKDIR /app/
|
7 |
+
|
8 |
+
WORKDIR /opt
|
9 |
+
|
10 |
+
# install dev tools
|
11 |
+
RUN apt-get update && apt-get install -y \
|
12 |
+
vim neovim nano \
|
13 |
+
git git-lfs \
|
14 |
+
zip unzip \
|
15 |
+
curl wget make build-essential xz-utils file tree \
|
16 |
+
sudo \
|
17 |
+
dnsutils \
|
18 |
+
tzdata language-pack-ja \
|
19 |
+
&& apt-get clean \
|
20 |
+
&& rm -rf /var/lib/apt/lists/*
|
21 |
+
|
22 |
+
# for Japanese settings
|
23 |
+
# ENV TZ Asia/Tokyo
|
24 |
+
# ENV LANG ja_JP.utf8
|
25 |
+
|
26 |
+
# for US settings
|
27 |
+
ENV LANG en_US.UTF-8
|
28 |
+
ENV LANGUAGE en_US
|
29 |
+
|
30 |
+
# install Python
|
31 |
+
RUN apt-get update && apt-get -yV upgrade && DEBIAN_FRONTEND=noninteractive apt-get -yV install \
|
32 |
+
build-essential libssl-dev libffi-dev \
|
33 |
+
python${PYTHON_VERSION} python${PYTHON_VERSION}-distutils python${PYTHON_VERSION}-dev \
|
34 |
+
&& ln -s /usr/bin/python${PYTHON_VERSION} /usr/local/bin/python3 \
|
35 |
+
&& ln -s /usr/bin/python${PYTHON_VERSION} /usr/local/bin/python \
|
36 |
+
&& apt-get clean \
|
37 |
+
&& rm -rf /var/lib/apt/lists/*
|
38 |
+
|
39 |
+
## install pip
|
40 |
+
RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \
|
41 |
+
&& python3 get-pip.py \
|
42 |
+
&& pip3 --no-cache-dir install --upgrade pip
|
43 |
+
|
44 |
+
## install Poetry
|
45 |
+
RUN curl -sSL https://install.python-poetry.org | python3 -
|
46 |
+
ENV PATH $PATH:/root/.local/bin
|
47 |
+
RUN poetry config virtualenvs.create true \
|
48 |
+
&& poetry config virtualenvs.in-project false
|
49 |
+
|
50 |
+
WORKDIR ${WORKDIR}
|
51 |
+
|
52 |
+
# install python packages
|
53 |
+
COPY poetry.lock pyproject.toml ./
|
54 |
+
COPY src ./src
|
55 |
+
RUN poetry install --no-dev
|
56 |
+
|
57 |
+
FROM base AS dev
|
58 |
+
WORKDIR ${WORKDIR}
|
59 |
+
|
60 |
+
# install python packages
|
61 |
+
COPY poetry.lock pyproject.toml ./
|
62 |
+
COPY src ./src
|
63 |
+
RUN poetry install
|
64 |
+
|
65 |
+
# Hugging Face Hub Settings
|
66 |
+
CMD ["poetry", "run", "streamlit", "run", "src/app.py", "--server.port", "7860"]
|
Makefile
ADDED
File without changes
|
compose.yaml
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
version: "3.2"
|
2 |
+
services:
|
3 |
+
binarual_beats_generator:
|
4 |
+
tty: true
|
5 |
+
stdin_open: true
|
6 |
+
user: root
|
7 |
+
working_dir: /app
|
8 |
+
build:
|
9 |
+
context: .
|
10 |
+
dockerfile: docker/cpu/Dockerfile
|
11 |
+
target: dev
|
12 |
+
# secrets:
|
13 |
+
# - github_token
|
14 |
+
args:
|
15 |
+
progress: plain
|
16 |
+
volumes:
|
17 |
+
- type: bind
|
18 |
+
source: ./
|
19 |
+
target: /app
|
20 |
+
ports:
|
21 |
+
- "8501:8501"
|
22 |
+
command:
|
23 |
+
poetry run streamlit run src/app.py
|
24 |
+
environment:
|
25 |
+
PYTHONPATH: "/app/src"
|
26 |
+
PYTHONUNBUFFERED: 1
|
27 |
+
# secrets:
|
28 |
+
# github_token:
|
29 |
+
# file: ${HOME}/.git-credentials
|
docker/cpu/Dockerfile
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
FROM ubuntu:22.04 AS base
|
2 |
+
|
3 |
+
ARG PYTHON_VERSION=3.10
|
4 |
+
|
5 |
+
ENV DEBIAN_FRONTEND=noninteractive
|
6 |
+
ENV WORKDIR /app/
|
7 |
+
|
8 |
+
WORKDIR /opt
|
9 |
+
|
10 |
+
# install dev tools
|
11 |
+
RUN apt-get update && apt-get install -y \
|
12 |
+
vim neovim nano \
|
13 |
+
git git-lfs \
|
14 |
+
zip unzip \
|
15 |
+
curl wget make build-essential xz-utils file tree \
|
16 |
+
sudo \
|
17 |
+
dnsutils \
|
18 |
+
tzdata language-pack-ja \
|
19 |
+
&& apt-get clean \
|
20 |
+
&& rm -rf /var/lib/apt/lists/*
|
21 |
+
|
22 |
+
# for Japanese settings
|
23 |
+
# ENV TZ Asia/Tokyo
|
24 |
+
# ENV LANG ja_JP.utf8
|
25 |
+
|
26 |
+
# for US settings
|
27 |
+
ENV LANG en_US.UTF-8
|
28 |
+
ENV LANGUAGE en_US
|
29 |
+
|
30 |
+
# install Python
|
31 |
+
RUN apt-get update && apt-get -yV upgrade && DEBIAN_FRONTEND=noninteractive apt-get -yV install \
|
32 |
+
build-essential libssl-dev libffi-dev \
|
33 |
+
python${PYTHON_VERSION} python${PYTHON_VERSION}-distutils python${PYTHON_VERSION}-dev \
|
34 |
+
&& ln -s /usr/bin/python${PYTHON_VERSION} /usr/local/bin/python3 \
|
35 |
+
&& ln -s /usr/bin/python${PYTHON_VERSION} /usr/local/bin/python \
|
36 |
+
&& apt-get clean \
|
37 |
+
&& rm -rf /var/lib/apt/lists/*
|
38 |
+
|
39 |
+
## install pip
|
40 |
+
RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \
|
41 |
+
&& python3 get-pip.py \
|
42 |
+
&& pip3 --no-cache-dir install --upgrade pip
|
43 |
+
|
44 |
+
## install Poetry
|
45 |
+
RUN curl -sSL https://install.python-poetry.org | python3 -
|
46 |
+
ENV PATH $PATH:/root/.local/bin
|
47 |
+
RUN poetry config virtualenvs.create true \
|
48 |
+
&& poetry config virtualenvs.in-project false
|
49 |
+
|
50 |
+
WORKDIR ${WORKDIR}
|
51 |
+
|
52 |
+
# install python packages
|
53 |
+
COPY poetry.lock pyproject.toml ./
|
54 |
+
COPY src ./src
|
55 |
+
RUN poetry install --no-dev
|
56 |
+
|
57 |
+
FROM base AS dev
|
58 |
+
WORKDIR ${WORKDIR}
|
59 |
+
|
60 |
+
# install python packages
|
61 |
+
COPY poetry.lock pyproject.toml ./
|
62 |
+
COPY src ./src
|
63 |
+
RUN poetry install
|
env.sample
ADDED
File without changes
|
images/app_sample.png
ADDED
notebooks/helloworld.ipynb
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [
|
3 |
+
{
|
4 |
+
"cell_type": "code",
|
5 |
+
"execution_count": 1,
|
6 |
+
"id": "18edcb70-64a5-4d17-94c0-a86ecc435be4",
|
7 |
+
"metadata": {},
|
8 |
+
"outputs": [
|
9 |
+
{
|
10 |
+
"name": "stdout",
|
11 |
+
"output_type": "stream",
|
12 |
+
"text": [
|
13 |
+
"hello world\n"
|
14 |
+
]
|
15 |
+
}
|
16 |
+
],
|
17 |
+
"source": [
|
18 |
+
"print(\"hello world\")"
|
19 |
+
]
|
20 |
+
},
|
21 |
+
{
|
22 |
+
"cell_type": "code",
|
23 |
+
"execution_count": null,
|
24 |
+
"id": "b90e3e1f-5aa1-43a0-b9e2-1d1bcaf9ff94",
|
25 |
+
"metadata": {},
|
26 |
+
"outputs": [],
|
27 |
+
"source": []
|
28 |
+
}
|
29 |
+
],
|
30 |
+
"metadata": {
|
31 |
+
"kernelspec": {
|
32 |
+
"display_name": "Python 3 (ipykernel)",
|
33 |
+
"language": "python",
|
34 |
+
"name": "python3"
|
35 |
+
},
|
36 |
+
"language_info": {
|
37 |
+
"codemirror_mode": {
|
38 |
+
"name": "ipython",
|
39 |
+
"version": 3
|
40 |
+
},
|
41 |
+
"file_extension": ".py",
|
42 |
+
"mimetype": "text/x-python",
|
43 |
+
"name": "python",
|
44 |
+
"nbconvert_exporter": "python",
|
45 |
+
"pygments_lexer": "ipython3",
|
46 |
+
"version": "3.9.5"
|
47 |
+
}
|
48 |
+
},
|
49 |
+
"nbformat": 4,
|
50 |
+
"nbformat_minor": 5
|
51 |
+
}
|
poetry.lock
ADDED
The diff for this file is too large to render.
See raw diff
|
|
pyproject.toml
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[tool.poetry]
|
2 |
+
name = "brainwave"
|
3 |
+
version = "0.1.0"
|
4 |
+
description = ""
|
5 |
+
authors = ["iamtatsuki05 <tatsukio0522@gmail.com>"]
|
6 |
+
packages = [
|
7 |
+
{ include = "brainwave", from = "src/" },
|
8 |
+
]
|
9 |
+
|
10 |
+
[tool.poetry.dependencies]
|
11 |
+
python = "^3.10"
|
12 |
+
python-dotenv = "^1.0.0"
|
13 |
+
setuptools = "^69.0.3"
|
14 |
+
fire = "^0.5.0"
|
15 |
+
pydantic = "^2.5.3"
|
16 |
+
beautifulsoup4 = "^4.12.2"
|
17 |
+
selenium = "^4.16.0"
|
18 |
+
fastapi = "^0.108.0"
|
19 |
+
uvicorn = "^0.25.0"
|
20 |
+
matplotlib = "^3.5.1"
|
21 |
+
pandas = "^1.4.2"
|
22 |
+
seaborn = "^0.11.2"
|
23 |
+
japanize-matplotlib = "^1.1.3"
|
24 |
+
numpy = "^1.22.3"
|
25 |
+
jupyterlab = "^3.3.4"
|
26 |
+
tqdm = "^4.64.0"
|
27 |
+
scikit-learn = "^1.1.1"
|
28 |
+
openpyxl = "^3.1.2"
|
29 |
+
streamlit = "^1.34.0"
|
30 |
+
|
31 |
+
[tool.poetry.group.dev.dependencies]
|
32 |
+
pytest = "^7.0.0"
|
33 |
+
ipykernel = ">=6.13.0"
|
34 |
+
autopep8 = ">=1.6.0"
|
35 |
+
autoflake = ">=1.4"
|
36 |
+
flake8 = ">=4.0.1"
|
37 |
+
flake8-isort = ">=4.1.1"
|
38 |
+
flake8-quotes = ">=3.3.1"
|
39 |
+
flake8-print = ">=4.0.0"
|
40 |
+
isort = ">=5.10.1"
|
41 |
+
black = ">=22.10.0"
|
42 |
+
mypy = ">=0.971"
|
43 |
+
tox = ">=3.25.1"
|
44 |
+
pre-commit = ">=3.3.3"
|
45 |
+
nbstripout = "0.6.1"
|
46 |
+
|
47 |
+
[tool.isort]
|
48 |
+
line_length = 88
|
49 |
+
multi_line_output = 3
|
50 |
+
include_trailing_comma = true
|
51 |
+
|
52 |
+
[tool.black]
|
53 |
+
skip-string-normalization = true
|
54 |
+
|
55 |
+
[build-system]
|
56 |
+
requires = ["poetry-core>=1.0.0"]
|
57 |
+
build-backend = "poetry.core.masonry.api"
|
scripts/main.py
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
if __name__ == '__main__':
|
2 |
+
print('Hello, World!')
|
src/__init__.py
ADDED
File without changes
|
src/app.py
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import base64
|
2 |
+
from io import BytesIO
|
3 |
+
|
4 |
+
import scipy.io.wavfile as wav
|
5 |
+
import streamlit as st
|
6 |
+
|
7 |
+
from brainwave.config.app import (
|
8 |
+
BASE_FREQUENCY_DEFAULT,
|
9 |
+
BASE_FREQUENCY_RANGE_MAX,
|
10 |
+
BASE_FREQUENCY_RANGE_MIN,
|
11 |
+
BASE_FREQUENCY_STEP,
|
12 |
+
BEAT_FREQUENCY_RANGE_MAX,
|
13 |
+
BEAT_FREQUENCY_RANGE_MIN,
|
14 |
+
BRAIN_WAVES,
|
15 |
+
DURATION_DEFAULT,
|
16 |
+
DURATION_RANGE_MAX,
|
17 |
+
DURATION_RANGE_MIN,
|
18 |
+
)
|
19 |
+
from brainwave.utils.binaural_beats import generate_binaural_beats
|
20 |
+
|
21 |
+
|
22 |
+
def app():
|
23 |
+
st.title('Binaural Beats Generator')
|
24 |
+
|
25 |
+
st.subheader('Brain Wave Selection')
|
26 |
+
selected_wave: str = st.selectbox(
|
27 |
+
'Select a type of brain wave:', list(BRAIN_WAVES.keys())
|
28 |
+
)
|
29 |
+
default_beat: int = BRAIN_WAVES[selected_wave]
|
30 |
+
|
31 |
+
st.subheader('Base Frequency (Hz)')
|
32 |
+
base_frequency: int = st.slider(
|
33 |
+
'Base Frequency (Hz):',
|
34 |
+
min_value=BASE_FREQUENCY_RANGE_MIN,
|
35 |
+
max_value=BASE_FREQUENCY_RANGE_MAX,
|
36 |
+
value=BASE_FREQUENCY_DEFAULT,
|
37 |
+
step=BASE_FREQUENCY_STEP,
|
38 |
+
)
|
39 |
+
base_frequency_input: int = st.number_input(
|
40 |
+
'...or enter the base frequency using the keyboard:',
|
41 |
+
min_value=BASE_FREQUENCY_RANGE_MIN,
|
42 |
+
max_value=BASE_FREQUENCY_RANGE_MAX,
|
43 |
+
value=base_frequency,
|
44 |
+
step=BASE_FREQUENCY_STEP,
|
45 |
+
)
|
46 |
+
|
47 |
+
st.subheader('Beat Frequency (Hz)')
|
48 |
+
beat_frequency: int = st.slider(
|
49 |
+
'Select the beat frequency using the slider:',
|
50 |
+
min_value=BEAT_FREQUENCY_RANGE_MIN,
|
51 |
+
max_value=BEAT_FREQUENCY_RANGE_MAX,
|
52 |
+
value=default_beat,
|
53 |
+
)
|
54 |
+
beat_frequency_input: int = st.number_input(
|
55 |
+
'...or enter the beat frequency using the keyboard:',
|
56 |
+
min_value=BEAT_FREQUENCY_RANGE_MIN,
|
57 |
+
max_value=BEAT_FREQUENCY_RANGE_MAX,
|
58 |
+
value=beat_frequency,
|
59 |
+
)
|
60 |
+
|
61 |
+
st.subheader('Duration (seconds)')
|
62 |
+
duration: int = st.slider(
|
63 |
+
'Duration (seconds):',
|
64 |
+
min_value=DURATION_RANGE_MIN,
|
65 |
+
max_value=DURATION_RANGE_MAX,
|
66 |
+
value=DURATION_DEFAULT,
|
67 |
+
)
|
68 |
+
duration_input: int = st.number_input(
|
69 |
+
'...or enter the duration using the keyboard:',
|
70 |
+
min_value=DURATION_RANGE_MIN,
|
71 |
+
max_value=DURATION_RANGE_MAX,
|
72 |
+
value=duration,
|
73 |
+
)
|
74 |
+
|
75 |
+
base_frequency = base_frequency_input
|
76 |
+
beat_frequency = beat_frequency_input
|
77 |
+
duration = duration_input
|
78 |
+
|
79 |
+
if st.button('Generate Sound'):
|
80 |
+
audio_data, sample_rate = generate_binaural_beats(
|
81 |
+
base_frequency, beat_frequency, duration
|
82 |
+
)
|
83 |
+
wav_file: BytesIO = BytesIO()
|
84 |
+
wav.write(wav_file, sample_rate, audio_data)
|
85 |
+
wav_file.seek(0)
|
86 |
+
|
87 |
+
b64: str = base64.b64encode(wav_file.read()).decode()
|
88 |
+
audio_html: str = (
|
89 |
+
f'<audio controls loop><source src="data:audio/wav;base64,{b64}" '
|
90 |
+
f'type="audio/wav"></audio>'
|
91 |
+
)
|
92 |
+
st.markdown(audio_html, unsafe_allow_html=True)
|
93 |
+
|
94 |
+
href: str = (
|
95 |
+
f'<a href="data:file/wav;base64,{b64}" download="'
|
96 |
+
f'binaural_beats_{selected_wave}.wav">Download '
|
97 |
+
f'{selected_wave} Binaural Beat</a>'
|
98 |
+
)
|
99 |
+
st.markdown(href, unsafe_allow_html=True)
|
100 |
+
|
101 |
+
|
102 |
+
if __name__ == '__main__':
|
103 |
+
app()
|
src/brainwave/__init__.py
ADDED
File without changes
|
src/brainwave/common/__init__.py
ADDED
File without changes
|
src/brainwave/common/utils/__init__.py
ADDED
File without changes
|
src/brainwave/config/__init__.py
ADDED
File without changes
|
src/brainwave/config/app.py
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import Final
|
2 |
+
|
3 |
+
BRAIN_WAVES: Final[dict[str, int]] = {
|
4 |
+
'Alpha Waves': 10, # Typically 8-13 Hz
|
5 |
+
'Beta Waves': 20, # Typically 14-30 Hz
|
6 |
+
'Theta Waves': 6, # Typically 4-7 Hz
|
7 |
+
'Delta Waves': 2, # Typically 0.5-3 Hz
|
8 |
+
'Gamma Waves': 40, # Typically 30-100 Hz
|
9 |
+
}
|
10 |
+
|
11 |
+
BASE_FREQUENCY_RANGE_MIN: Final[int] = 1
|
12 |
+
BASE_FREQUENCY_RANGE_MAX: Final[int] = 500
|
13 |
+
BASE_FREQUENCY_DEFAULT: Final[int] = 200
|
14 |
+
BASE_FREQUENCY_STEP: Final[int] = 10
|
15 |
+
|
16 |
+
BEAT_FREQUENCY_RANGE_MIN: Final[int] = 1
|
17 |
+
BEAT_FREQUENCY_RANGE_MAX: Final[int] = 100
|
18 |
+
|
19 |
+
DURATION_RANGE_MIN: Final[int] = 1
|
20 |
+
DURATION_RANGE_MAX: Final[int] = 300
|
21 |
+
DURATION_DEFAULT: Final[int] = 30
|
src/brainwave/env.py
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
from pathlib import Path
|
2 |
+
|
3 |
+
PACKAGE_DIR = Path(__file__).parents[2]
|
src/brainwave/main.py
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
def main():
|
2 |
+
print('Hello, World!')
|
3 |
+
|
4 |
+
|
5 |
+
if __name__ == '__main__':
|
6 |
+
main()
|
src/brainwave/utils/__init__.py
ADDED
File without changes
|
src/brainwave/utils/binaural_beats.py
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import Optional
|
2 |
+
|
3 |
+
import numpy as np
|
4 |
+
|
5 |
+
|
6 |
+
def generate_binaural_beats(
|
7 |
+
base_freq: int,
|
8 |
+
beat_freq: int,
|
9 |
+
duration: int,
|
10 |
+
fs: Optional[int] = 44100,
|
11 |
+
) -> tuple[np.ndarray, int]:
|
12 |
+
n_samples: int = int(fs * duration)
|
13 |
+
t: np.ndarray = np.arange(n_samples) / fs
|
14 |
+
left_ear: np.ndarray = np.sin(2 * np.pi * base_freq * t)
|
15 |
+
right_ear: np.ndarray = np.sin(2 * np.pi * (base_freq + beat_freq) * t)
|
16 |
+
stereo_sound: np.ndarray = np.vstack((left_ear, right_ear)).T
|
17 |
+
stereo_normalized: np.ndarray = np.int16(
|
18 |
+
(stereo_sound / np.max(np.abs(stereo_sound))) * 32767
|
19 |
+
)
|
20 |
+
return stereo_normalized, fs
|
tests/brainwave/__init__.py
ADDED
File without changes
|