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_holophonic_binaural(base_freq, beat_freq, duration, volume, holophonic, 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) if holophonic: # 音が左右に揺れ動くパン効果をつける pan = 0.5 * (1 + np.sin(2 * np.pi * 0.2 * t)) # 0.2Hzで左右に揺れる left *= (1 - pan) right *= pan 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_holophonic_binaural( base_freq=base_freq_slider.get(), beat_freq=brainwave_freqs[selection], duration=duration_slider.get(), volume=volume_slider.get(), holophonic=bool(holophonic_var.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_holophonic_binaural( base_freq=base_freq_slider.get(), beat_freq=brainwave_freqs[selection], duration=duration_slider.get(), volume=volume_slider.get(), holophonic=bool(holophonic_var.get()) ) suffix = "_holo" if holophonic_var.get() else "" filename = f"{selection.split()[0]}_{base_freq_slider.get()}Hz_{duration_slider.get()}s{suffix}.wav" write(filename, sr, (stereo * 32767).astype(np.int16)) messagebox.showinfo("保存完了", f"{filename} を保存しました。") # GUI構築 root = tk.Tk() root.title("ホロフォニック・バイノーラルビートジェネレーター") root.geometry("520x460") 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() # ホロフォニックON/OFF holophonic_var = tk.IntVar() tk.Checkbutton(root, text="ホロフォニック効果を有効にする(左右パンニング)", variable=holophonic_var).pack(pady=10) frame = tk.Frame(root) frame.pack(pady=15) 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()