[{"data":1,"prerenderedAt":494},["ShallowReactive",2],{"content-/tts-narration-bpm120":3,"all-pages-for-dir":473,"related-/tts-narration-bpm120":474,"og-image-/tts-narration-bpm120":493},{"id":4,"title":5,"body":6,"category":455,"concepts":456,"description":457,"extension":458,"meta":459,"navigation":460,"ogImage":456,"path":461,"project_name":456,"published":462,"publishedAt":463,"seo":464,"source":456,"stem":465,"tags":466,"todo":471,"unpublished":462,"updatedAt":456,"__hash__":472},"pages/2026-08/2026-08-18/tts-narration-bpm120.md","自分の声を複製して、BPM120のビートに乗せる — TTSで講義音声を作る実験",{"type":7,"value":8,"toc":440},"minimark",[9,18,25,36,41,48,66,79,91,140,146,149,152,159,166,169,176,181,188,191,195,202,209,212,216,222,229,271,277,288,292,295,336,342,349,356,359,362,390,397,400,434],[10,11,12,13,17],"p",{},"動画のナレーションを自分で録ると、毎回テンポが違う。「えー」「あー」が入る。言い間違えて録り直す。切り貼りの手間もかかる。",[14,15,16],"strong",{},"話す内容は撮影前から決まっているのだから、読み上げは機械にやらせたほうが早い","のではないか。",[10,19,20,21,24],{},"そう考えて、自分の声を複製し、",[14,22,23],{},"文と文の間をBPM120のビートグリッドに揃える","ところまでやってみた。触って確かめられるページも作ってある。",[10,26,27],{},[28,29,35],"a",{"href":30,"target":31,"rel":32},"/labs/tts-beat-preview.html","_blank",[33,34],"noopener","noreferrer","→ 検証ページを開く（波形・ビート・ズレの実測つき）",[37,38,40],"h2",{"id":39},"なぜ-bpm-120-なのか","なぜ BPM 120 なのか",[10,42,43,44,47],{},"きっかけは、お笑い芸人が「BPM120でやるといい」と話していたという又聞きだった。",[14,45,46],{},"その発言の出典は探したが見つからなかった","ので、ここでは確認できた事実だけを並べる。",[10,49,50,53,54,59,60,65],{},[14,51,52],{},"BPM 120 は「人が歩くテンポ」である。"," 行進曲の標準速度がここに置かれていて、",[28,55,58],{"href":56,"target":31,"rel":57},"https://ongakuyougo.conceptmol.com/%E3%83%9E%E3%83%BC%E3%83%81%E3%83%86%E3%83%B3%E3%83%9D/",[33,34],"マーチテンポ（音楽用語）","によれば、軍隊の行進は1分間におよそ120歩を基準としてきた。",[28,61,64],{"href":62,"target":31,"rel":63},"https://bpm-music-walking.com/walking06/",[33,34],"ウォーキングとテンポの関係","でも、心地よく歩けるのは110〜120あたりとされる。人間の身体が持っているテンポということになる。",[10,67,68,69,72,73,78],{},"一方、",[14,70,71],{},"日本語の読み上げの目安は「1分間300字」が広く使われている","。",[28,74,77],{"href":75,"target":31,"rel":76},"https://speech.gokoro.net/blog/technique/speech-rate.html",[33,34],"話し方教室の解説","によれば、NHKのアナウンサーが1分間300文字を基準にしていて、番組制作の共通認識になっているという。",[10,80,81,82,85,86,90],{},"この2つを同じ物差しに乗せると、こうなる。日本語の話速をBPMに換算するときは「",[14,83,84],{},"1モーラ＝16分音符","」とするのが通例で、",[87,88,89],"code",{},"BPM = モーラ毎分 ÷ 4"," で計算できる。",[92,93,94,110],"table",{},[95,96,97],"thead",{},[98,99,100,103,107],"tr",{},[101,102],"th",{},[101,104,106],{"align":105},"right","話速",[101,108,109],{"align":105},"相当BPM",[111,112,113,127],"tbody",{},[98,114,115,119,122],{},[116,117,118],"td",{},"NHKのニュース読み（300字/分）",[116,120,121],{"align":105},"382モーラ/分",[116,123,124],{"align":105},[14,125,126],{},"95",[98,128,129,132,135],{},[116,130,131],{},"BPM120 に合わせた場合",[116,133,134],{"align":105},"480モーラ/分",[116,136,137],{"align":105},[14,138,139],{},"120",[10,141,142,145],{},[14,143,144],{},"BPM120 はニュース読みより26%速い。"," ゆっくり噛んで含めるテンポではなく、教育系の動画やショート動画で使われる速さに近い。芸人の話が本当だとすれば、「間を持たせない、聞き手を待たせない速さ」という意味だったのだろうと思う。",[37,147,148],{"id":148},"実験したこと",[10,150,151],{},"自分の声を4本・約38秒録音し、それを参照音声にして日本語特化の音声合成モデル（Irodori-TTS）で12文のナレーションを作った。合成そのものは手元のMacで完結していて、インターネットには出ていない。",[10,153,154,155,158],{},"そのうえで、",[14,156,157],{},"文の配置を音楽のグリッドに乗せた","。句点のあとは1小節（BPM120で2.0秒）のグリッドに置き、文の頭が必ず小節の頭から始まるようにする。こうすると、4つ打ちのキックと文頭が毎回一致する。",[10,160,161,165],{},[28,162,164],{"href":30,"target":31,"rel":163},[33,34],"検証ページ","では、話速（BPM120/130/140）とグリッド（1小節・2拍・1拍）を切り替えながら、ビートを重ねて聴き比べられる。波形の上に小節線と拍線を引いてあり、文の立ち上がりがどれだけズレているかをミリ秒で表示する。",[37,167,168],{"id":168},"見つかった落とし穴",[10,170,171,172,175],{},"配置の計算は最初から合っていた。にもかかわらず、耳では毎回わずかに遅れて聞こえる。原因は3つあった。",[14,173,174],{},"いずれも「合成音の無音」が犯人","だった。",[177,178,180],"h3",{"id":179},"_1-先頭の無音で全文が遅れる","1. 先頭の無音で、全文が遅れる",[10,182,183,184,187],{},"合成音の頭には0.28秒ほどの無音が入る。グリッド線にファイルの先頭を合わせると、",[14,185,186],{},"声が出るのはその0.28秒後","になる。実測すると平均451ms・最大784msの遅れがあった。8分音符1つぶんに相当するので、音楽に重ねれば確実に聞こえる。",[10,189,190],{},"先頭の無音ぶんだけクリップを前へずらすと、平均0ms・最大0msになった。",[177,192,194],{"id":193},"_2-末尾の無音で間が2秒伸びる","2. 末尾の無音で、間が2秒伸びる",[10,196,197,198,201],{},"こちらのほうが厄介だった。ある文の直後だけ、明らかに間延びして聞こえる箇所があった。調べると、その文はグリッド線を",[14,199,200],{},"わずか10ミリ秒だけ","超えて終わっていた。グリッド配置は「次の線から始める」ので、次の線まで丸ごと2秒待つことになる。",[10,203,204,205,208],{},"そして10ミリ秒の超過を作っていたのは、",[14,206,207],{},"その文の末尾についていた0.39秒の無音","だった。声そのものは線の手前で終わっていたのに、無音まで長さに数えていたために線を越えてしまっていた。",[10,210,211],{},"前後どちらの無音も除いて配置するよう直すと、この箇所の間は1.99秒から0.65秒になり、全体も55.0秒から47.0秒に縮んだ。",[177,213,215],{"id":214},"_3-話速の測り方を間違えると2割ずれる","3. 話速の測り方を間違えると、2割ずれる",[10,217,218,221],{},[14,219,220],{},"これが一番の間違いだった。"," 話速を「ファイル全体の秒数」で割って計算していたため、1文あたり0.6秒の無音（12文で約11秒）が分母に混ざり、実態より2割遅く見えていた。",[10,223,224,225,228],{},"その結果「BPM120にするには×1.35が必要」と判断したのだが、正しく声だけで測ると×1.35は",[14,226,227],{},"BPM149","だった。速すぎて当然である。",[92,230,231,243],{},[95,232,233],{},[98,234,235,237,240],{},[101,236],{},[101,238,239],{"align":105},"誤（無音込み）",[101,241,242],{"align":105},"正（声だけ）",[111,244,245,258],{},[98,246,247,250,253],{},[116,248,249],{},"素のまま",[116,251,252],{"align":105},"BPM 89",[116,254,255],{"align":105},[14,256,257],{},"BPM 111",[98,259,260,263,266],{},[116,261,262],{},"×1.35",[116,264,265],{"align":105},"BPM 120",[116,267,268],{"align":105},[14,269,270],{},"BPM 149",[10,272,273,274,72],{},"正しく測ると、素のままで既にBPM111あった。BPM120に必要な倍率は、",[14,275,276],{},"×1.089 にすぎない",[10,278,279,280,283,284,287],{},"なお倍率は一度の計算では合わない。速度変換とmp3化を通すと無音の境目がわずかに動くため、",[87,281,282],{},"480 ÷ 実測"," で出した倍率でも0.4%ずれた。",[14,285,286],{},"実際に作った音を測って倍率を補正する","処理を入れて、実測BPM120.2まで追い込んでいる。",[37,289,291],{"id":290},"参照音声のテンポは合成音に転写されない","参照音声のテンポは、合成音に転写されない",[10,293,294],{},"「クリックを聞きながら参照音声を録れば、リズムがそのまま合成音に乗るのではないか」という発想が出たので、これも測った。",[92,296,297,308],{},[95,298,299],{},[98,300,301,303,305],{},[101,302],{},[101,304,106],{"align":105},[101,306,307],{"align":105},"BPM",[111,309,310,323],{},[98,311,312,315,318],{},[116,313,314],{},"録音した参照音声",[116,316,317],{"align":105},"485モーラ/分",[116,319,320],{"align":105},[14,321,322],{},"121.2",[98,324,325,328,331],{},[116,326,327],{},"そこから作った合成音",[116,329,330],{"align":105},"443モーラ/分",[116,332,333],{"align":105},[14,334,335],{},"110.7",[10,337,338,341],{},[14,339,340],{},"偶然ほぼBPM120で読んでいたのに、合成音は約9%遅くなっている。"," このモデルは文の長さを自分で予測する仕組みを持っていて、参照音声から受け取るのは主に声質、テンポはモデル側の判断が優先されるらしい。",[10,343,344,345,348],{},"つまり参照音声をメトロノームに合わせて録っても、狙ったテンポでは出てこない。ただし",[14,346,347],{},"出発点が近いほど、後段の速度調整が小さくて済む","という意味はある。速度変換は倍率が大きいほど不自然になるので、そこは効く。",[10,350,351,352,355],{},"拍にきっちり乗せたいなら、合成を挟まず",[14,353,354],{},"自分でクリックを聞きながら録る","ほうが確実になる。その場合はイヤホン必須で、スピーカーで流すとクリックがマイクに回り込む。",[37,357,358],{"id":358},"この方式が実務で楽な理由",[10,360,361],{},"動画で話す内容は撮影前に決まっていることが多い。決めてから喋るなら、次の手間がまるごと消える。",[363,364,365,372,378,384],"ul",{},[366,367,368,371],"li",{},[14,369,370],{},"言い間違えても、テキストを直して作り直すだけ","。録り直しがいらない",[366,373,374,377],{},[14,375,376],{},"「えー」「あー」が入らない","。フィラーの除去が不要になる",[366,379,380,383],{},[14,381,382],{},"文の切れ目が最初からビートに乗っている","。編集で詰めたり伸ばしたりする作業がいらない",[366,385,386,389],{},[14,387,388],{},"BGMを重ねるだけで成立する","。文頭とキックが揃っているので、合わせ込みが要らない",[10,391,392,393,396],{},"最後の点が思ったより大きい。",[14,394,395],{},"間の設計を先に数値で決めてしまえば、音楽との同期は後工程ではなく前提条件になる","。切り貼りで合わせるのではなく、最初から合っているものが出てくる。",[37,398,399],{"id":399},"まとめ",[363,401,402,405,411,418,425,431],{},[366,403,404],{},"BPM120 は人が歩くテンポで、行進曲の標準。日本語の読み上げに当てるとニュース読みより26%速い",[366,406,407,408],{},"文の間をグリッドに乗せると、",[14,409,410],{},"文頭が毎回キックの1拍目に一致する",[366,412,413,414,417],{},"合成音の",[14,415,416],{},"前後の無音を配置計算から除く","こと。これを外すと、遅れと間延びの両方が起きる",[366,419,420,421,424],{},"話速は",[14,422,423],{},"声だけの秒数","で測ること。ファイル長で測ると2割ずれる",[366,426,427,428],{},"目標BPMへの倍率は",[14,429,430],{},"実際に作った音を測って補正する",[366,432,433],{},"参照音声のテンポは合成音に転写されない。声質だけが引き継がれる",[10,435,436],{},[28,437,439],{"href":30,"target":31,"rel":438},[33,34],"→ 検証ページ（波形・ビート・ズレの実測）",{"title":441,"searchDepth":442,"depth":442,"links":443},"",2,[444,445,446,452,453,454],{"id":39,"depth":442,"text":40},{"id":148,"depth":442,"text":148},{"id":168,"depth":442,"text":168,"children":447},[448,450,451],{"id":179,"depth":449,"text":180},3,{"id":193,"depth":449,"text":194},{"id":214,"depth":449,"text":215},{"id":290,"depth":442,"text":291},{"id":358,"depth":442,"text":358},{"id":399,"depth":442,"text":399},"dev",null,"話速も文と文の間も数値で固定すれば、TTSのナレーションは音楽のグリッドに乗る。自分の声のクローンで実験し、波形で検証したときに見つかった3つの落とし穴","md",{},true,"/tts-narration-bpm120",false,"2026-08-18T00:00:00.000Z",{"title":5,"description":457},"2026-08/2026-08-18/tts-narration-bpm120",[467,468,469,470],"音声合成","ナレーション","Web Audio","実験","memo","BYGJ_Kk0Xu6ateixwmWvvYTj0EQR07E0cih15SI0Nv8",[],[475,479,483,486,490],{"title":476,"path":477,"publishedAt":478},"ナレーションの話速をBPMで設計する。実測BPM98と、間をビートに乗せる試み","/narration-bpm-beat-grid","2026-08-14T00:00:00.000Z",{"title":480,"path":481,"publishedAt":482},"会計学習コンテンツのナレーション機能構築 - VOICEVOX・GCP TTS・Cloudflare R2","/narration-feature-voicevox-gcp-tts","2026-03-15T00:00:00.000Z",{"title":484,"path":485,"publishedAt":463},"Windowsのマイクで録ってMacに届ける — ブラウザを「マイクのドライバ」として使う","/browser-mic-lan-post-to-mac",{"title":487,"path":488,"publishedAt":489},"Synthesia風「降ってくる音符」のピアノアプリをWeb Audio + Canvasで作った——実装の詳細メモ","/piano-roll-implementation","2026-06-11T00:00:00.000Z",{"title":491,"path":492,"publishedAt":489},"スクショ1枚からSynthesia風ピアノロールWebアプリを作ってもらった日——88鍵Canvas＋Web Audio合成＋運指表示","/piano-roll-web-app","https://log.eurekapu.com/favicon.svg",1787053849584]