Suzuna — STATE Ph3.x-v2 録音品質UI / RVC学習適性ワークステーション
概要
Phase 1〜3で構築した変換・学習・TTSパイプラインに、 録音品質を担保するための前処理UIを追加する。
コンセプト:「AIを賢くする」ではなく「ユーザーを失敗させない」
単なる録音補助ではなく、RVC学習データの品質を底上げする 「RVC学習適性ワークステーション」として設計する。
アーキテクチャ
ブラウザ側(Web Audio API)
getUserMedia → MediaStream
├── AnalyserNode → リアルタイム波形・音量メーター(canvas)
└── MediaRecorder → 録音 WAV
Python側(ファイル処理のみ)
POST /audio/score → 学習適性スコア算出
POST /audio/process → 前処理適用
POST /audio/env-check → 環境音評価(3秒WAVを受け取り判定)
音声処理パイプライン
録音 / インポート
↓
① 無音トリミング (自動)
↓
② ノイズリダクション (自動 / 強度調整可)
↓
③ ローカット / ハイカット(デフォルト値あり / スライダー調整可)
↓
④ ゲイン調整 (オートノーマライズ or 手動)
↓
⑤ 学習適性スコア表示 (自動算出)
↓
学習データとして保存 / RVC変換へ
重要: パイプライン順序は変更しないこと NR前にゲインするとノイズまで増幅して音質が劣化する。
UI構成
サイドバー順
声質変換 (Ph1)
音声前処理 (Ph3.x) ← ここ
モデル学習 (Ph2)
TTSスタジオ (Ph3)
録音パネル
┌─ 録音 ────────────────────────────────────────┐
│ [🎤 録音開始] │
│ │
│ 波形: ▁▂▄▆▄▂▁▃▅▃▁ (リアルタイム) │
│ ← 緑=適正 / 黄=小さい / 赤=クリッピング │
│ │
│ 音量: [████████░░] -12dB ← 適正 │
│ ⚠ クリッピング警告 / ⚠ 小さすぎ警告 │
│ │
│ 環境音: 静か ✅ / ノイズ多め ⚠ / 大きい ❌ │
└─────────────────────────────────────────────────┘
波形カラーリング(CSSのみで実装)
| 状態 | 色 | 条件 |
|---|---|---|
| 適正 | --color-primary(グリーン) | -24〜-6dB |
| 小さい | --color-warning(橙) | -24dB以下 |
| クリッピング | --color-error(赤) | -3dB以上 |
録音前環境音チェック(マイク接続時に自動実行)
- 3秒間の環境音を計測
- ノイズレベルを判定 → UIバッジ表示
- ✅ 静か(-50dB以下)
- ⚠ ノイズあり(-50〜-35dB)
- ❌ 大きい(-35dB以上)
音声処理パネル
┌─ 音声処理 ─────────────────────────────────────┐
│ 入力: voice_001.wav [▶試聴] │
│ │
│ [✅ 無音トリミング] 自動検出・除去 │
│ │
│ ノイズリダクション 強度: 0.5 │
│ [──────●──────────] │
│ │
│ ローカット 80 Hz │
│ [●───────────────] 20〜500Hz │
│ │
│ ハイカット 16000 Hz │
│ [──────────────●─] 8k〜24kHz │
│ │
│ ゲイン調整 │
│ ○ オートノーマライズ(ピーク -3dB) │
│ ○ 手動 [──●──────] +0.0 dB (-12〜+12) │
│ │
│ [▶ 処理を適用] [↩ リセット] │
│ │
│ 出力: voice_001_processed.wav [▶試聴] │
└─────────────────────────────────────────────────┘
RVC学習適性スコアパネル
表示名は「録音品質」ではなく「RVC学習適性」とする。 ユーザーが本当に知りたいのは「いい音か」ではなく「学習に向いてるか」。
┌─ RVC学習適性 ──────────────────────────────────┐
│ │
│ 87 / 100 A │
│ │
│ ノイズレベル ████████░░ 良好 │
│ 音量安定度 ███████░░░ 普通 │
│ クリッピング ██████████ 問題なし │
│ 無音比率 █████████░ 良好 │
│ 子音明瞭度 ████████░░ 良好 ← NEW │
│ 部屋反響 ███████░░░ 普通 ← NEW │
│ │
│ 💡 音量安定度を上げるにはマイクとの距離を │
│ 一定に保ってください │
└─────────────────────────────────────────────────┘
グレード定義
| スコア | グレード | 意味 |
|---|---|---|
| 90〜100 | S | 最高品質、即学習可 |
| 75〜89 | A | 良好、学習推奨 |
| 60〜74 | B | 普通、前処理で改善を |
| 40〜59 | C | 要改善、再録音を検討 |
| 0〜39 | D | 学習非推奨、再録音推奨 |
スコア算出ロジック(6項目)
| 項目 | 配点 | 算出方法 |
|---|---|---|
| ノイズレベル | 25点 | SNR(信号対雑音比)から換算 |
| 音量安定度 | 20点 | RMS音量の分散から換算 |
| クリッピング | 20点 | サンプル値が0.99以上の割合 |
| 無音比率 | 15点 | 無音区間が全体の20〜40%が理想 |
| 子音明瞭度 | 10点 | 4kHz〜8kHz帯域のエネルギー比率 ← NEW |
| 部屋反響 | 10点 | 簡易RT60推定(decay rate)← NEW |
新規スコア項目の詳細
子音明瞭度(10点)
RVCは母音より子音の変換が難しく、子音が潰れると機械感が出る。 s / t / k / sh などの高域成分(4kHz〜8kHz)のエネルギー比率を見る。
def calc_consonant_score(y, sr):
# 4kHz〜8kHzのエネルギー比率
stft = np.abs(librosa.stft(y))
freqs = librosa.fft_frequencies(sr=sr)
consonant_mask = (freqs >= 4000) & (freqs <= 8000)
consonant_energy = stft[consonant_mask].mean()
total_energy = stft.mean()
ratio = consonant_energy / (total_energy + 1e-10)
# 理想比率: 0.15〜0.35
score = 10 if 0.15 <= ratio <= 0.35 else max(0, 10 - abs(ratio - 0.25) * 40)
return int(score)
将来的なアドバイス例:
- 「子音が潰れています → マイクとの距離を少し離してください」
- 「高域が多すぎます → ハイカットを14kHzに下げてみてください」
部屋反響スコア(10点)
簡易RT60推定で残響時間を計測。残響が多いと学習データに部屋の音が混入する。
def calc_reverb_score(y, sr):
# 簡易RT60推定: エネルギーの減衰率を見る
energy = librosa.feature.rms(y=y)[0]
decay_rate = np.polyfit(np.arange(len(energy)), np.log(energy + 1e-10), 1)[0]
# decay_rateが急峻 = 残響少ない = 良い
if decay_rate < -0.05:
return 10 # デッド(理想)
elif decay_rate < -0.02:
return 7 # 普通
else:
return 3 # 反響あり
将来的なアドバイス例:
- 「部屋の反響が多いです → 布団や毛布を壁際に置くと改善します」
- 「クローゼットの中での録音が効果的です」
adviceシステム
現在は固定文、将来的に動的生成に拡張できる設計にしておく。
def get_advice(scores: dict) -> str | None:
if scores["clipping"] < 15:
return "音が割れています。マイクの音量を下げるか、距離を離してください"
if scores["noise"] < 15:
return "ノイズが多いです。エアコンや換気扇を止めて録音してください"
if scores["stability"] < 12:
return "音量が不安定です。マイクとの距離を一定に保ってください"
if scores["reverb"] < 5:
return "部屋の反響が多いです。布団を横に置くか、クローゼット内での録音を試してください"
if scores["consonant"] < 5:
return "子音が聞き取りにくいです。マイクに少し近づいて、はっきり発音してください"
return None
将来的な拡張方向
- フォルマント変動 → 「マイクに近づいたり離れたりしています」
- 低域比率変化 → 「ポップノイズが検出されました(ポップガード推奨)」
- 有声/無声比率 → 「話すペースが速すぎます」
Pythonバックエンド
依存ライブラリ
librosa # 波形解析・特徴量抽出 (ISC License) ※重い、~150MB
scipy # フィルター処理 (BSD)
noisereduce # ノイズリダクション (MIT)
soundfile # WAV読み書き (BSD)
numpy # 数値演算 (BSD)
⚠ librosaは依存チェーンが重い。インストール時間に注意。
API
POST /audio/process
body: {
input_path: string,
trim_silence: bool, // default: true
noise_reduce: float, // 0〜1, default: 0.5 (0=無効)
lowcut_hz: int, // default: 80
highcut_hz: int, // default: 16000
gain_mode: "auto" | "manual",
gain_db: float // -12〜+12, default: 0
}
response: {
output_path: string,
score: QualityScore
}
POST /audio/score
body: { input_path: string }
response: QualityScore
POST /audio/env-check
body: { wav_base64: string } // 3秒の環境音WAV
response: {
noise_level_db: float,
status: "quiet" | "noisy" | "loud"
}
型定義
interface QualityScore {
total: number // 0〜100
grade: "S" | "A" | "B" | "C" | "D"
noise: number // 0〜25
stability: number // 0〜20
clipping: number // 0〜20
silence_ratio: number // 0〜15
consonant: number // 0〜10 (NEW)
reverb: number // 0〜10 (NEW)
advice?: string
}
デフォルト値まとめ
| パラメーター | デフォルト | 推奨範囲 | 備考 |
|---|---|---|---|
| 無音トリミング | ON | — | 常時推奨 |
| ノイズリダクション | 0.5 | 0.3〜0.7 | 強すぎると声質劣化 |
| ローカット | 80Hz | 60〜200Hz | ファン・エアコン除去 |
| ハイカット | 16000Hz | 12k〜20kHz | 高周波ノイズ除去 |
| ゲインモード | オート | — | ピーク -3dBFS |
新規・変更ファイル
| ファイル | 種別 | 内容 |
|---|---|---|
python/routers/audio_process.py | 新規 | 3エンドポイント + 6項目スコア算出 |
python/server.py | 変更 | audio_process router追加 |
src/pages/AudioQualityPage.tsx | 新規 | 音声前処理メインページ |
src/components/WaveformMeter.tsx | 新規 | リアルタイム波形 + 音量バー(canvas) |
src/components/QualityScorePanel.tsx | 新規 | RVC学習適性スコア表示(6項目) |
src/lib/api.ts | 変更 | QualityScore型 + 3 APIメソッド追加 |
src/App.tsx | 変更 | AudioQualityPageルーティング追加 |
src/components/layout/Sidebar.tsx | 変更 | 「音声前処理」ナビ追加(声質変換の次) |
完了条件
- リアルタイム波形・音量メーター(Web Audio API + canvas)
- 波形カラーリング(緑/黄/赤)
- 録音前環境音チェック(3秒計測)
- 無音トリミング
- ノイズリダクション(強度スライダー)
- ローカット / ハイカットフィルター
- ゲイン調整(オート / 手動)
- RVC学習適性スコア表示(6項目 + グレード + アドバイス)
- 子音明瞭度スコア
- 部屋反響スコア
- 処理前後の試聴比較
将来フェーズ(Phase 4以降)
- adviceの動的生成(フォルマント変動・ポップノイズ検出)
- 録音距離安定度(RMS + 低域比率 + 音量揺れの複合判定)
- 「録音が上手くなる」フィードバックループ設計