← スキル物語 「SSOTから探して」と言ったら過去の失敗を掘り返してきた話 必須タグがなくても8割の点数が出てしまった話 →
第29話

歌詞は合格点なのに歌は冴えなかった話——品質チェックが「言葉」から「音」へ進んだ話


ある日のこと、曲づくりの品質チェックで不思議なことが起きた。歌詞の点検を通すと「✅合格」。力強い言葉も抑揚のある構成も揃っている。ところが実際に生成された音源を聞くと、低い声で囁くような、今ひとつ冴えない歌だった。点検係(Claude)は困った。「言葉は合格と言っている。音は別のことを言っている。どちらを信じればいいんだ?」

原因は、点検係が歌詞の「文字」しか見ていなかったことだった。破裂音の多い力強い語彙や、行ごとの音節のばらつきを数えて判定する仕組みだったから、歌そのものが低音でモノトーンでも、紙の上では立派に見えてしまう。紙の点検で満点でも、ステージで崩れる芸人のようなものである。

そこで点検係は方針を変えた。「文字」に加えて「音そのもの」を測る装置を付けよう。実際の音源から「声の明るさ」(高音成分がどれだけ占めるか)と「音程の揺れ」(抑揚の幅)を実測する。ただし、ここで気をつけたのが旧 checker の扱いだった。捨てて完全に音だけにすると、これまで培った17本のテストが一度に無効になってしまう。そこで「実測50%・文字列50%」の融合評価にして、様子を見ながら割合を動かす、という移行方式にした。

もう一つ、地味だが効いた工夫がある。あの失敗曲を「お手本(逆)」としてテストデータに残したことだ。低音ウィスパーで冴えたあの音源は、新しい音の点検が本当に失敗を検出できるかを試す「問題集」として使われた。失敗は捨てるものではなく、点検の教材になる。

<details><summary>▶ 技術的にどうなってるか</summary>

実測の2軸 — ①中高音使用率: librosa.feature.spectral_centroid() でスペクトル重心の時系列を求め、A4(440Hz)以上のフレーム比率を実測値とする(0.4以上=OK)。②抑揚幅: librosa.pyin() で音高時系列を推定し標準偏差を取る。pYIN は無音区間で -1 を返すため、np.nan に置換してから nanstd で除外計算する(20未満=モノトーン判定)。

融合戦略 — 軸B/C とも 0.5 * 実測 + 0.5 * 文字列(Phase 1) の加重平均。完全置換案(D')は Phase 1 の17テストが全滅して回帰テストが貧弱になるため却下し、1〜2ヶ月の運用統計で重みを 0.7/0.3 等へ調整する設計。

TDDの拡張 — Phase 1 の17テストを継承しつつ、実測ベースの新規テスト5本を追加。fixtures には失敗事例 v2_低音ウィスパー.wav と成功事例 祭礼前夜_chorus.wav を用意し、「失敗が検出できること」「成功が検出できること」の双方向を確認する。エラーハンドリングは wav 不在=終了コード2、音程推定全滅=「実測不可」表示、librosa 未導入時は対話的に pip 導入を案内。

正典: obsidian-ssot/01_DECISIONS/ai-music/2026-07-12_音節密度ルール拡張-Phase2実測オーディオ解析導入.md

</details>