Skip to content

TTS 送信前に英語駅名のマクロンを除去して誤読を防ぐ#6407

Merged
TinyKitten merged 1 commit into
devfrom
fix/tts-strip-macron
Jul 12, 2026
Merged

TTS 送信前に英語駅名のマクロンを除去して誤読を防ぐ#6407
TinyKitten merged 1 commit into
devfrom
fix/tts-strip-macron

Conversation

@TinyKitten

@TinyKitten TinyKitten commented Jul 12, 2026

Copy link
Copy Markdown
Member

概要

TTS API へ送る英語アナウンス文からヘボン式長音符(マクロン)を除去し、マクロン付きの英語駅名(例: Tōkyō / Kiryū / Ōhirashita)が誤読・無音化される問題を防ぎます。

変更の種類

  • バグ修正
  • 新機能
  • リファクタリング
  • ドキュメント
  • CI/CD
  • その他

変更内容

  • ttsSpeechFetcher に送信直前のマクロン除去を追加。normalize('NFD') で結合マクロン(U+0304)へ分解 → 除去 → normalize('NFC') で再結合し、ō → o などへ正規化する(既存の useIsDifferentStationName と同じ手法)。
  • SSML のタグ(<...>)は属性ごと保護し、タグ外の可視テキストだけを対象にすることで、<phoneme ph="..."> の IPA 発音記号を壊さず温存する。
  • キャッシュキーも除去後のテキストで生成し、マクロンの有無で同一音声のキャッシュを共有する。
  • 日本語側の SSML は元々マクロンを含まないため対象外(英語テキストのみ処理)。
  • テストを 4 件追加(可視テキストのマクロン除去 / SSML タグ・IPA 属性の保持 / マクロン有無でのキャッシュ共有)。

テスト

  • npm run lint が通ること
  • npm test が通ること
  • npm run typecheck が通ること

関連Issue

スクリーンショット(任意)

Summary by CodeRabbit

  • 改善
    • 英語の音声合成で、可視テキスト中のマクロン(長音記号)を自動的に除去するようになりました。
    • SSMLタグや発音記号は維持され、正規化後のテキストが音声合成とキャッシュに反映されます。
    • マクロンの有無にかかわらず同じキャッシュが利用され、不要な再取得を抑制します。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@TinyKitten TinyKitten self-assigned this Jul 12, 2026
@github-actions github-actions Bot added the react label Jul 12, 2026
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

英語SSMLの可視テキストからマクロンを除去する処理を追加し、正規化結果をキャッシュキーとTTSリクエストに適用しました。タグやphoneme属性の保持、キャッシュヒットをテストで検証しています。

Changes

英語SSMLマクロン正規化

Layer / File(s) Summary
SSMLマクロン除去処理
src/utils/ttsSpeechFetcher.ts
SSMLタグ外の可視テキストだけをNFD分解し、マクロンを除去してNFCへ再合成します。
キャッシュとTTSリクエストへの適用
src/utils/ttsSpeechFetcher.ts, src/utils/ttsSpeechFetcher.test.ts
正規化済みテキストをキャッシュキーとssmlEnに使用し、タグ・phoneme属性の保持とキャッシュ共有を検証します。

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • TrainLCD/MobileApp#6235: 同じfetchSpeechAudioのタイムアウト処理とテストを変更しています。

Poem

ぴょんと跳ねて、マクロン消す
タグはそのまま、音を鳴らす
キャッシュの道もひとつに整え
二度目の呼び声、すぐ届く
うさぎも満足、ぴょんぴょんぴょん!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed PRタイトルは英語駅名のマクロン除去によるTTS誤読防止という主変更を的確に表しています。
Description check ✅ Passed 必須の「概要」「変更の種類」「変更内容」「テスト」が揃っており、テンプレート要件を概ね満たしています。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/tts-strip-macron

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/utils/ttsSpeechFetcher.test.ts (1)

212-234: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

ph属性の検証文字がマクロン除去の対象外。

コメントでは「ph 属性内の IPA (長音 ː) はそのまま」保持されることを検証する意図ですが、ː(U+02D0 MODIFIER LETTER TRIANGULAR COLON)はstripMacronsが対象とする結合マクロン(U+0304)とは異なる文字です。そのため、このテストは「タグ内テキストがマクロン除去処理を通過しない」ことを直接的には証明できていません(ːはタグ外に出しても除去されないため)。

タグ保護ロジックをより厳密に検証するなら、属性値に実際のマクロン付き文字(例: ph="toːkjoō" のような形)を含めるとよいでしょう。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/ttsSpeechFetcher.test.ts` around lines 212 - 234, Update the test
case around fetchSpeechAudio to include an actual U+0304 combining macron in the
phoneme ph attribute, such as the suggested IPA value, while retaining a
visible-text macron that should be removed. Adjust the expected ssmlEn assertion
so it verifies the attribute macron is preserved and only the visible text is
normalized.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/utils/ttsSpeechFetcher.test.ts`:
- Around line 212-234: Update the test case around fetchSpeechAudio to include
an actual U+0304 combining macron in the phoneme ph attribute, such as the
suggested IPA value, while retaining a visible-text macron that should be
removed. Adjust the expected ssmlEn assertion so it verifies the attribute
macron is preserved and only the visible text is normalized.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bb6e9e5b-f93d-47db-b050-1fa1c5f1e169

📥 Commits

Reviewing files that changed from the base of the PR and between b91a4b8 and e14e32b.

📒 Files selected for processing (2)
  • src/utils/ttsSpeechFetcher.test.ts
  • src/utils/ttsSpeechFetcher.ts

@TinyKitten TinyKitten merged commit 54d3de7 into dev Jul 12, 2026
7 checks passed
@TinyKitten TinyKitten deleted the fix/tts-strip-macron branch July 12, 2026 13:01
@TinyKitten TinyKitten mentioned this pull request Jul 12, 2026
9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant