94 lines
3.2 KiB
Python
94 lines
3.2 KiB
Python
import numpy as np
|
||
import sounddevice as sd
|
||
from scipy.io.wavfile import write
|
||
import tkinter as tk
|
||
from tkinter import ttk, messagebox
|
||
|
||
# 脳波タイプと対応するビート周波数
|
||
brainwave_freqs = {
|
||
"Delta (深い睡眠)": 2,
|
||
"Theta (瞑想・創造)": 6,
|
||
"Alpha (リラックス・集中)": 10,
|
||
"Beta (活動・思考)": 20,
|
||
"Gamma (高度認知)": 40
|
||
}
|
||
|
||
# バイノーラルビートを生成
|
||
def generate_binaural(base_freq, beat_freq, duration, volume, sample_rate=44100):
|
||
t = np.linspace(0, duration, int(sample_rate * duration), endpoint=False)
|
||
left = np.sin(2 * np.pi * base_freq * t)
|
||
right = np.sin(2 * np.pi * (base_freq + beat_freq) * t)
|
||
stereo = np.stack([left, right], axis=1)
|
||
return (stereo * volume).astype(np.float32), sample_rate
|
||
|
||
# 再生ボタンの処理
|
||
def play_sound():
|
||
selection = combo.get()
|
||
if selection not in brainwave_freqs:
|
||
messagebox.showerror("エラー", "脳波タイプを選択してください。")
|
||
return
|
||
|
||
stereo, sr = generate_binaural(
|
||
base_freq=base_freq_slider.get(),
|
||
beat_freq=brainwave_freqs[selection],
|
||
duration=duration_slider.get(),
|
||
volume=volume_slider.get()
|
||
)
|
||
sd.play(stereo, samplerate=sr)
|
||
sd.wait()
|
||
|
||
# 保存ボタンの処理
|
||
def save_wav():
|
||
selection = combo.get()
|
||
if selection not in brainwave_freqs:
|
||
messagebox.showerror("エラー", "脳波タイプを選択してください。")
|
||
return
|
||
|
||
stereo, sr = generate_binaural(
|
||
base_freq=base_freq_slider.get(),
|
||
beat_freq=brainwave_freqs[selection],
|
||
duration=duration_slider.get(),
|
||
volume=volume_slider.get()
|
||
)
|
||
filename = f"{selection.split()[0]}_{base_freq_slider.get()}Hz_{duration_slider.get()}s.wav"
|
||
write(filename, sr, (stereo * 32767).astype(np.int16))
|
||
messagebox.showinfo("保存完了", f"{filename} を保存しました。")
|
||
|
||
# GUI作成
|
||
root = tk.Tk()
|
||
root.title("脳波バイノーラルビート ジェネレーター Pro")
|
||
root.geometry("500x400")
|
||
|
||
# 脳波選択
|
||
tk.Label(root, text="脳波を選択:", font=("Arial", 13)).pack(pady=5)
|
||
combo = ttk.Combobox(root, values=list(brainwave_freqs.keys()), font=("Arial", 12), state="readonly")
|
||
combo.pack(pady=5)
|
||
|
||
# ベース周波数スライダー
|
||
tk.Label(root, text="ベース周波数(Hz):", font=("Arial", 11)).pack()
|
||
base_freq_slider = tk.Scale(root, from_=100, to=1000, orient="horizontal", resolution=10)
|
||
base_freq_slider.set(400)
|
||
base_freq_slider.pack()
|
||
|
||
# 音量スライダー
|
||
tk.Label(root, text="音量(0.0〜1.0):", font=("Arial", 11)).pack()
|
||
volume_slider = tk.Scale(root, from_=0.0, to=1.0, resolution=0.01, orient="horizontal")
|
||
volume_slider.set(0.5)
|
||
volume_slider.pack()
|
||
|
||
# 時間スライダー
|
||
tk.Label(root, text="再生時間(秒):", font=("Arial", 11)).pack()
|
||
duration_slider = tk.Scale(root, from_=5, to=60, orient="horizontal")
|
||
duration_slider.set(10)
|
||
duration_slider.pack()
|
||
|
||
# ボタン
|
||
frame = tk.Frame(root)
|
||
frame.pack(pady=20)
|
||
|
||
tk.Button(frame, text="▶ 再生", command=play_sound, width=15).pack(side="left", padx=10)
|
||
tk.Button(frame, text="💾 保存(.wav)", command=save_wav, width=15).pack(side="right", padx=10)
|
||
|
||
root.mainloop()
|
||
|