126 lines
4.7 KiB
Python
126 lines
4.7 KiB
Python
import tkinter as tk
|
||
from tkinter import messagebox, filedialog
|
||
import subprocess
|
||
import os
|
||
|
||
CHEAT_SHEET = '''; === SBaGen チートシート ===
|
||
; 書式: 時間 左-右 チャンネル オプション
|
||
; 例: +0:00:00 400-410 L
|
||
|
||
; 左400Hz, 右410Hz → 10Hzビート(L=左基準)
|
||
+0:00:00 400-410 L
|
||
|
||
; 時間経過後の周波数変化(10分後に420Hz/430Hzへ)
|
||
+0:10:00 420-430 L
|
||
|
||
; 音声終了(20分後)
|
||
+0:20:00 off
|
||
|
||
; 背景音の追加(最初に記述)
|
||
_ = mix(nature.wav, 0.3)
|
||
|
||
; ノイズを加える(例: white, pink)
|
||
_ = mix(white, 0.1)
|
||
|
||
; チャンネル指定:
|
||
; L = 左ベース(左耳に指定周波数、右に +差分)
|
||
; R = 右ベース
|
||
; S = ステレオ完全分離(各耳に別の周波数)
|
||
'''
|
||
|
||
class SBGEditor:
|
||
def __init__(self, master):
|
||
self.master = master
|
||
master.title("SBaGen GUIエディタ(環境音対応)")
|
||
master.geometry("640x580")
|
||
|
||
self.steps = []
|
||
self.env_file = None
|
||
self.env_volume = tk.DoubleVar(value=0.3)
|
||
|
||
self.frame = tk.Frame(master)
|
||
self.frame.pack(pady=10)
|
||
|
||
tk.Label(self.frame, text="時間(+HH:MM:SS)").grid(row=0, column=0)
|
||
tk.Label(self.frame, text="左耳周波数").grid(row=0, column=1)
|
||
tk.Label(self.frame, text="右耳周波数").grid(row=0, column=2)
|
||
|
||
self.time_entry = tk.Entry(self.frame)
|
||
self.left_entry = tk.Entry(self.frame)
|
||
self.right_entry = tk.Entry(self.frame)
|
||
self.time_entry.grid(row=1, column=0)
|
||
self.left_entry.grid(row=1, column=1)
|
||
self.right_entry.grid(row=1, column=2)
|
||
|
||
tk.Button(self.frame, text="追加", command=self.add_step).grid(row=1, column=3, padx=10)
|
||
|
||
env_frame = tk.LabelFrame(master, text="🔊 環境音の追加(mix)", padx=10, pady=10)
|
||
env_frame.pack(padx=10, pady=10, fill="x")
|
||
|
||
tk.Button(env_frame, text="環境音を選択(WAV/MP3)", command=self.select_env_file).pack(pady=5)
|
||
|
||
tk.Label(env_frame, text="音量:").pack()
|
||
tk.Scale(env_frame, from_=0.0, to=1.0, resolution=0.01, variable=self.env_volume, orient="horizontal").pack(fill="x")
|
||
|
||
self.env_label = tk.Label(env_frame, text="現在: 未選択")
|
||
self.env_label.pack()
|
||
|
||
# スクリプト表示欄
|
||
self.script_box = tk.Text(master, height=20)
|
||
self.script_box.pack(padx=10, pady=10, fill="both", expand=True)
|
||
self.script_box.insert("1.0", CHEAT_SHEET)
|
||
|
||
btn_frame = tk.Frame(master)
|
||
btn_frame.pack(pady=10)
|
||
|
||
tk.Button(btn_frame, text="💾 保存(.sbg)", command=self.save_file, width=20).pack(side="left", padx=10)
|
||
tk.Button(btn_frame, text="▶ 再生(sbagen)", command=self.play_sbagen, width=20).pack(side="right", padx=10)
|
||
|
||
def add_step(self):
|
||
time = self.time_entry.get()
|
||
left = self.left_entry.get()
|
||
right = self.right_entry.get()
|
||
if not (time and left and right):
|
||
messagebox.showwarning("未入力", "すべてのフィールドを入力してください。")
|
||
return
|
||
line = f"{time} {left}-{right} L"
|
||
self.script_box.insert("end", line + "\n")
|
||
self.steps.append(line)
|
||
|
||
def select_env_file(self):
|
||
file = filedialog.askopenfilename(filetypes=[("音声ファイル", "*.wav *.mp3")])
|
||
if file:
|
||
self.env_file = file
|
||
self.env_label.config(text=f"現在: {os.path.basename(file)}")
|
||
|
||
def insert_env_mix(self, text_lines):
|
||
if self.env_file:
|
||
path = os.path.abspath(self.env_file).replace("\\", "/")
|
||
mix_line = f"_ = mix({path}, {self.env_volume.get():.2f})"
|
||
text_lines.insert(0, mix_line)
|
||
return text_lines
|
||
|
||
def save_file(self):
|
||
filename = filedialog.asksaveasfilename(defaultextension=".sbg", filetypes=[("SBaGen Script", "*.sbg")])
|
||
if filename:
|
||
lines = self.script_box.get("1.0", "end").strip().split("\n")
|
||
full_script = self.insert_env_mix(lines)
|
||
with open(filename, "w") as f:
|
||
f.write("\n".join(full_script))
|
||
messagebox.showinfo("保存完了", f"{filename} を保存しました。")
|
||
|
||
def play_sbagen(self):
|
||
lines = self.script_box.get("1.0", "end").strip().split("\n")
|
||
full_script = self.insert_env_mix(lines)
|
||
with open("temp_play.sbg", "w") as f:
|
||
f.write("\n".join(full_script))
|
||
try:
|
||
subprocess.run(["./sbagen-1.4.5/sbagen", "temp_play.sbg"])
|
||
except FileNotFoundError:
|
||
messagebox.showerror("再生失敗", "sbagen が見つかりません。パスを確認してください。")
|
||
|
||
if __name__ == "__main__":
|
||
root = tk.Tk()
|
||
app = SBGEditor(root)
|
||
root.mainloop()
|