Skip to content

IPA生成処理を #1531 (7bf7f17) 時点に戻す#1548

Merged
TinyKitten merged 2 commits into
devfrom
claude/tts-ipa-generation-rollback-xa4hrv
Jun 23, 2026
Merged

IPA生成処理を #1531 (7bf7f17) 時点に戻す#1548
TinyKitten merged 2 commits into
devfrom
claude/tts-ipa-generation-rollback-xa4hrv

Conversation

@TinyKitten

@TinyKitten TinyKitten commented Jun 23, 2026

Copy link
Copy Markdown
Member

概要

TTS の IPA 生成が全体的に正しく発音できなくなっていたため、IPA 生成処理を #1531 (7bf7f17) 時点のものに戻します。#1532 以降の Azure TTS 向け書き換えシリーズを撤回します。

変更の種類

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

変更内容

テスト

SQLX_OFFLINE=true cargo test --lib --package stationapi で 341 件すべて pass(復元した 7bf7f17 系テストと維持した #1533 のテストの両方を含む)。

  • cargo fmt --all -- --check が通ること
  • cargo clippy -- -D warnings が通ること
  • cargo testSQLX_OFFLINE=true)が通ること

関連Issue

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


Generated by Claude Code

Summary by CodeRabbit

リリースノート

  • 改善
    • 駅名・線名の音声表記生成ロジックを見直し、表記の揺れを抑えて精度を向上しました(路線名の扱い、英語混在を含む発音など)。
  • テスト
    • 音声表記の出力仕様に合わせて、期待値や検証条件を更新しました。

Azure TTS 向けの IPA 書き換えシリーズ (#1532, #1534/#1535, #1538,
#1539, #1543, #1545, #1546) が全体的に正しく発音できなくなっていたため、
IPA 生成処理を #1531 (7bf7f17) 時点のものに戻す。

対象:
- domain/ipa.rs: 7bf7f17 へ復元(ジ=ʤ 表記、路線 name_ipa の
  「線」→ " laɪn" 等の英語接尾辞付与、語末撥音 ɴ、長音は母音分割など)
- dto/line.rs / dto/station.rs: 上記に対応するテスト期待値を 7bf7f17 へ復元

ただし #1533「路線名の name_ipa・name_tts_segments が null/空になる不具合
修正」は Azure 対応とは独立した実バグ修正のため、削除せず維持する
(中黒「・」・全角/半角括弧を語の区切りとして空白に変換し、区切り由来の
余分な空白を正規化)。回帰テストも合わせて維持。

列車種別の重複排除 (#1540/#1541) 等、IPA 生成と無関係な変更は据え置き。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X4tdXHjrFBNqWerrAdGe9n
@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1025a566-85e9-4790-a052-cd1df775fa03

📥 Commits

Reviewing files that changed from the base of the PR and between 330811f and 451b740.

📒 Files selected for processing (1)
  • stationapi/src/use_case/dto/line.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • stationapi/src/use_case/dto/line.rs

📝 Walkthrough

Walkthrough

katakana_to_ipa の音韻ルールエンジンを全面書き直し、鼻音同化(m/ɲ/ŋ/n/ɴ)・長母音出力・音節境界挿入の動作を変更した。compute_line_ipa はステム/サフィックス分離方式に変更され、メモ化エントリー compute_line_ipa_cached が追加された。英語トラックの ɾl 側音化後処理が廃止された。3ファイルにわたる多数のテスト期待値が新しい音韻出力に合わせて更新された。

Changes

IPA音韻パイプライン改修と関連テスト更新

Layer / File(s) Summary
line IPA エントリーポイントとサフィックス置換
stationapi/src/domain/ipa.rs
IpaCacheKey 型エイリアス導入。compute_line_ipareplace_line_name_suffix でステム/サフィックスを分離し、ステムのみを katakana_to_ipa に渡す方式へ変更。メモ化エントリー compute_line_ipa_cached とサフィックスマップ/例外リストを追加。
音韻ルールエンジン全面書き直し
stationapi/src/domain/ipa.rs
apply_phonological_rules を全面リファクタリングし、鼻音同化分類(m/ɲ/ŋ/n/ɴ)・長母音 ː の直接出力・insert_syllable_breaks による音節境界挿入を刷新。空白正規化を split_whitespace().join(" ") に変更。 の IPA を dʑiʤi に、kutchan/shim の末尾鼻音を ɴ に変更。station_name_to_tts_segments から lateralize_ra_row パスを廃止。
ipa.rs 単体テスト期待値更新
stationapi/src/domain/ipa.rs
ケイセイ・メイテツ・トウキョウ等の長母音スタイル(keːseːke.ise.i)、イナゲカイガン/メジロ/シンヨコハマの鼻音・ジ IPA、英語トラック(Rinkai・Narita等)の lateralize 廃止に伴う期待値を更新。replace_line_name_suffix および開眼系サフィックステストも更新・拡張。
line.rs / station.rs DTO テスト期待値更新
stationapi/src/use_case/dto/line.rs, stationapi/src/use_case/dto/station.rs
line.rsname_ipa テスト群を新フォーマットへ更新し、line_name_k 中心の入力設定・京成本線 IPA 期待値変更・中黒路線名テストの Some 非空検証への緩和を実施。station.rsname_roman_ipaname_tts_segments 期待値を更新。

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • TrainLCD/StationAPI#1532: compute_line_ipa および katakana→IPA 音韻ルール( マッピング含む)の変更が重複し、line.rsname_ipa 期待値更新が直接関連する。
  • TrainLCD/StationAPI#1545: ipa.rs における ɾl 側音化後処理の廃止と TTS セグメント期待値変更が本 PR と同一コードパス上にある。
  • TrainLCD/StationAPI#1546: station_name_to_tts_segments への lateralize_ra_row 追加が本 PR での同処理廃止と直接矛盾しており、同一コードパスを対象としている。

Suggested labels

fix

🐇 ふわふわ耳で聴き比べ、
ン の音が ɴ に変わった!
ケイセイが ke.ise.i になって、
鉄道の名前も IPA で踊る~
🎵 音節の境界、ぴょんと越えるよ!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed タイトルは「IPA生成処理を #1531 (7bf7f17) 時点に戻す」で、PRの主要な変更内容(IPA生成ロジックの復元)を明確かつ簡潔に説明しており、変更セットの主な意図を正しく伝えています。
Description check ✅ Passed PR説明は概要・変更の種類・変更内容・テスト・関連Issueといったテンプレートの主要セクションを備えており、バグ修正の理由、復元の具体的内容、テスト実行結果が明確に記述されています。
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 claude/tts-ipa-generation-rollback-xa4hrv

Warning

Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption.


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 (2)
stationapi/src/use_case/dto/line.rs (1)

438-439: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

中黒路線名テストの検証が弱く、回帰を見逃しやすいです。

Line 438-439 は Some かつ非空のみの確認になっており、 の正規化や 線 -> laɪn 置換が壊れても通過できます。最低限の不変条件を追加して契約を固定したほうが安全です。

差分案
-        assert!(grpc_line.name_ipa.is_some());
-        assert!(!grpc_line.name_ipa.as_deref().unwrap().is_empty());
+        let ipa = grpc_line.name_ipa.expect("name_ipa should be present");
+        assert!(!ipa.is_empty());
+        assert!(ipa.contains(" laɪn"));
+        assert!(!ipa.contains("  "));
+        assert!(!ipa.contains('・'));
🤖 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 `@stationapi/src/use_case/dto/line.rs` around lines 438 - 439, The assertions
at lines 438-439 for the middle dot line name test only verify that
grpc_line.name_ipa is Some and non-empty, which is insufficient to catch
regressions in normalization of the middle dot character '・' or the substitution
of '線' to 'laɪn'. Strengthen the test by adding specific assertions that
validate the actual expected content of grpc_line.name_ipa, such as checking for
the presence of expected substrings or matching against the complete expected
normalized value, rather than just checking for existence and non-emptiness.
stationapi/src/domain/ipa.rs (1)

1158-1168: 📐 Maintainability & Code Quality | 🔵 Trivial

last_vowel の戻り値が未使用のため、分岐ロジックが冗長です。

両分岐の結果は等価です。last_vowel(&output).is_some() は判定にしか使われず、どちらのブランチでも「末尾が ː でなければ追加」という動作に統一されています。シェル実行結果から last_vowel の呼び出しは本箇所のみであるため、ロジックを簡素化すれば関数自体を削除でき、clippy の dead_code 警告を回避できます。

♻️ 提案: 分岐の簡素化
             Phoneme::LongVowel => {
-                // Lengthen the preceding vowel
-                if last_vowel(&output).is_some() {
-                    // Check if already has ː
-                    if !output.ends_with('ː') {
-                        output.push('ː');
-                    }
-                } else {
-                    output.push('ː');
-                }
+                // Lengthen the preceding vowel (avoid doubling the marker)
+                if !output.ends_with('ː') {
+                    output.push('ː');
+                }
                 i += 1;
             }
🤖 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 `@stationapi/src/domain/ipa.rs` around lines 1158 - 1168, The branching logic
for the LongVowel phoneme case is redundant because both the if and else
branches perform the same operation: checking if the output ends with 'ː' and
adding it if not. Remove the unnecessary call to `last_vowel(&output).is_some()`
and simplify the logic to directly check `!output.ends_with('ː')` before pushing
the lengthening marker. This eliminates the redundant condition check and
unifies both code paths into a single, simpler statement that applies the same
lengthening logic regardless of the previous vowel detection.
🤖 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 `@stationapi/src/domain/ipa.rs`:
- Around line 1158-1168: The branching logic for the LongVowel phoneme case is
redundant because both the if and else branches perform the same operation:
checking if the output ends with 'ː' and adding it if not. Remove the
unnecessary call to `last_vowel(&output).is_some()` and simplify the logic to
directly check `!output.ends_with('ː')` before pushing the lengthening marker.
This eliminates the redundant condition check and unifies both code paths into a
single, simpler statement that applies the same lengthening logic regardless of
the previous vowel detection.

In `@stationapi/src/use_case/dto/line.rs`:
- Around line 438-439: The assertions at lines 438-439 for the middle dot line
name test only verify that grpc_line.name_ipa is Some and non-empty, which is
insufficient to catch regressions in normalization of the middle dot character
'・' or the substitution of '線' to 'laɪn'. Strengthen the test by adding specific
assertions that validate the actual expected content of grpc_line.name_ipa, such
as checking for the presence of expected substrings or matching against the
complete expected normalized value, rather than just checking for existence and
non-emptiness.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 28bc7b95-8fe3-40aa-a80a-0708f32f7eba

📥 Commits

Reviewing files that changed from the base of the PR and between 9465a0e and 330811f.

📒 Files selected for processing (3)
  • stationapi/src/domain/ipa.rs
  • stationapi/src/use_case/dto/line.rs
  • stationapi/src/use_case/dto/station.rs

CodeRabbit の指摘 (#1548) を受け、test_name_ipa_with_nakaguro_is_not_null の
検証を Some/非空のみから、「・」→空白正規化(連続空白なし)・「線」→ " laɪn"
置換まで確認する不変条件に強化する。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X4tdXHjrFBNqWerrAdGe9n
@TinyKitten TinyKitten merged commit 0d2a752 into dev Jun 23, 2026
11 checks passed
@TinyKitten TinyKitten deleted the claude/tts-ipa-generation-rollback-xa4hrv branch June 23, 2026 01:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants