Chord Romanizer
コード進行をローマ数字へ変換し、文脈を考慮した複数の機能解釈を返すライブラリです。 解析エンジンはRustで実装し、Pythonパッケージは高水準APIだけを公開する薄いラッパーになっています。
動作環境
- CPython 3.8以上
- Rust 1.85以上(ソースからビルドする場合のみ)
- ビルド方式: PyO3 + maturin
- Python ABI:
abi3-py38
abi3-py38 wheelは、同じOS・CPUアーキテクチャであればCPython 3.8以降の複数バージョンから利用できます。OSとCPUアーキテクチャをまたいで同じwheelを使うことはできません。
インストール
公開済みwheelを利用する場合:
python -m pip install chord-romanizer
リポジトリから開発用にインストールする場合:
python -m pip install "maturin>=1.9.4,<2" pytest
python -m maturin develop --release
python -m pytest -q
基本的な使い方
既存Python版との互換性を保つため、通常のコンストラクタはpython019プロファイルを使用します。
from chord_romanizer import Romanizer
romanizer = Romanizer(default_tonic="C")
results = romanizer.romanize_progression(["Dm7", "G7", "Cmaj7"])
print([result.roman for result in results])
# ['IIm7', 'V7', 'IM7']
コードごとに調を指定することもできます。
results = romanizer.romanize_progression(
[
("C", "C"),
("F", "C"),
("Dm7", "F"),
("G7", "F"),
]
)
StrictV1とk-best解析
修正済みの規則、候補を保持する解析、Blackadderコード解釈を利用する新規コードではRomanizer.strict()を推奨します。
from chord_romanizer import Romanizer
romanizer = Romanizer.strict(default_tonic="B")
paths = romanizer.analyze_top_k_interpretations(["Daug/C", "B"], k=3)
for path in paths:
print(path.total_score)
for selection in path.selections:
print(selection.label, selection.blackadder)
analyze_top_k_interpretations は和声的に異なる候補だけを返す高水準APIです。
異名同音の度数表記、増三和音の対称な回転表記、slash bassを省いただけの
表示は候補数を消費しません。進行格子の低水準パスを直接取得する場合は
analyze_top_kを使用します。
Blackadderの増三和音部分は、入力表記をwritten_upper_rootへ保持したまま、
bassのtritone上をcanonical_upper_rootとして一意に表示します。たとえば
G#aug/F#、Eaug/F#、Caug/F#はいずれもcanonical shapeがCaug/F#です。
意味候補を増やさず、元の綴りは解釈の証拠として利用できます。
analyze_top_kは単一の正解に固定せず、進行全体として自然な解釈をスコア順に返します。各AnalysisPathには次が含まれます。
selections: 各イベントで選んだ候補total_score: パス全体のスコアevidence: 加点・減点した規則と説明blackadder: 裏コード型、サブドミナント型などの構造・機能解釈
将来MIDIから得る調性・ボイシング・声部進行などをスコアリングへ加えられるよう、候補生成と経路選択は分離しています。
完全減七では異名同音の回転表記を別候補として水増しせず、和声的に異なる意味を
候補化します。たとえばC majorのI -> Idim7 -> IIm7は、
rootless_dominant_ninth、passing_diminished、tonic_substituteを
小さなtop-kで比較できます。bIIIdim7 -> Vもwritten rootだけで除外せず、
対称音集合からvii°7/Vとrootless II7(b9)の両方を検討します。
I -> Idim7 -> Iにはcommon_tone_diminishedと
auxiliary_diminishedを付けます。解決先にはmajor/minor qualityを要求するため、
G7 -> CdimのCdimをtonic targetとして扱いません。
裏コードではbVIm7 -> bII7 -> Iをrelated ii–subV–Iとして候補化します。
また、bVII7のmodal、subdominant-minor、backdoor候補を分離し、
bVI -> VではSDm候補、plain bII -> IではNeapolitan/Phrygian候補が
genericな半音接近より上位になるよう候補固有の遷移証拠を使用します。
機能・借用元・局所調の分類
harmonic_classificationsでは、和声的役割、dominantの解決関係、借用元、
全体調と局所調を別々の軸として返します。
results = Romanizer.strict("C").annotate_progression(["Em7-5", "Eb7", "Dm7"])
substitute = next(
item
for item in results[1].harmonic_classifications
if item.dominant_relation == "tritone_substitute"
)
print(substitute.role) # dominant
print(substitute.perspective.global_tonic) # C
print(substitute.perspective.local_tonic) # D
print(substitute.perspective.local_tonic_degree) # II
print(substitute.perspective.scope) # tonicization
したがってIIIm7-5–VI7–IIm7は、全体調の表記を失わずに、IIを一時主音とする
iiø–V–iとして分類できます。通常のV、裏コード、バックドアは同じ
dominant_relation軸を使用し、SDmなどの借用元とは同時に保持できます。
Global key・転調・ピボット
高水準APIはglobal keyと機能候補を同時に順位付けし、確認終止のある別調区間を modulation候補として返します。短い副属終止を転調へ強制せず、tonicizationの 読みもTop-kに残します。
paths = Romanizer.strict().analyze_keys_and_functions(
["C", "Am7", "D7", "G", "C", "D7", "G"],
global_key="C",
global_mode="major",
k=5,
)
for span in paths[0].modulations:
print(span.from_key, span.to_key, span.mechanism, span.pivot)
diatonic_pivot、chromatic_pivot、dominant_bridge、
dominant_sequence、direct_dominantを区別します。各イベントの
active_key、scope、is_pivot、is_modulation_confirmationは
解釈ツリーにも渡るため、UIで転調枝を選択して後続を再計算できます。
複数回の転調と原調復帰もfrom_key → to_keyの区間列として返します。
長期和声記憶
高水準key/function APIは、選択済みのactive keyに加えて最大2段の未解決
dominant目標を保持します。たとえばD7 → Am7 → Gでは、介在するAm7を
越えてD7のG目標を追跡します。
path = Romanizer.strict().analyze_keys_and_functions(
["C", "D7", "Am7", "G", "C"],
global_key="C",
global_mode="major",
k=5,
)[0]
print(path.selections[1].pending_resolutions)
print(path.harmonic_resolutions)
print(path.memory_score)
各ツリーノードにもkey_region_age_chords、pending_resolutions、
resolved_resolution_sourcesが渡るため、UIは「どの期待がどこで解決したか」を
線やbadgeで表示できます。通常の隣接V–Iは既存transitionと二重加点しません。
pending_predominantとcadential_spansは、介在和音を含む
Predominant → Dominant → Resolutionを3点の区間として返します。
secondary deceptive候補はdeceptive_arrivalとして目標を閉じるため、
正しい代理解決が未解決ペナルティを受けることはありません。
詳細はdocs/HARMONIC_MEMORY.mdを参照してください。
詳しい判定基準と現時点の限界は
docs/MODULATION.mdを参照してください。
N.C.と文脈境界
用途に合わせて2種類のAPIを用意しています。
from chord_romanizer import Boundary, Romanizer
progression = ["Dm7", "N.C.", Boundary("long silence"), "G7"]
romanizer = Romanizer.strict("C")
# コード結果だけが必要な従来型API。N.C.と境界は出力から除外される。
chords_only = romanizer.annotate_progression(progression)
# 入力位置を保つAPI。N.C.と境界もイベントとして返る。
aligned = romanizer.annotate_events(progression)
N.C.は休符表現として扱い、それだけでは前後の文脈を切りません。長い空白やセクション変更など、明示的に文脈を切る必要がある箇所へBoundaryを置きます。
Python APIの境界
Pythonから公開するのはRomanizerを中心とする高水準APIです。Rustの内部構造を大量のPyClassとして公開せず、ネイティブ拡張との境界は内部JSONに限定しています。このため、Rust側の候補表現やスコアリング実装を変更してもPython公開APIへの影響を抑えられます。
互換性のため、ChordParser、ParsedChord、ChordInterpreterも引き続きimportできます。ただしRomanizerによる調性・機能・進行の解析判断はRust側で行われます。
ネイティブバックエンドは次のように確認できます。
print(Romanizer().native_backend)
# {'version': '0.1.12', 'abi': 'abi3-py38'}
wheelのCIビルド
.github/workflows/wheels.ymlはpull request、main/masterへのpush、v*タグ、手動実行で次をビルドします。
| OS | アーキテクチャ | 成果物 |
|---|---|---|
| Linux | x86_64 | manylinux2014 cp38-abi3 wheel + sdist |
| Windows | x86_64 | cp38-abi3 wheel |
| macOS | Intel x86_64 | cp38-abi3 wheel |
| macOS | Apple Silicon arm64 | cp38-abi3 wheel |
各jobはwheelをインストールし、ソースツリー外へコピーしたテストを実行します。これにより、ローカルのPythonファイルではなく、実際にwheelへ収録されたネイティブ拡張が読み込まれることを確認します。workflowは成果物をGitHub Actions artifactへ保存しますが、PyPIへの公開は行いません。
ディレクトリ構成
chord_romanizer/ Python公開APIと互換データ型
chord-romanizer-py/ PyO3による非公開ネイティブbinding
chord-romanizer-rs/ Rust解析エンジン
docs/ 設計文書と調査資料
tests/ Python APIテスト
.github/workflows/ wheelビルドCI
Rust側だけを検証する場合:
cargo test --manifest-path chord-romanizer-rs/Cargo.toml
cargo test --manifest-path chord-romanizer-py/Cargo.toml
ライセンス
Metadata
Release files for chord-romanizer 0.1.12
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| chord_romanizer-0.1.12.tar.gz | 143.0 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| chord_romanizer-0.1.12-cp38-abi3-win_amd64.whl | CPython 3.8 | abi3 | Windows x86-64 | Details |
| chord_romanizer-0.1.12-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.8 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| chord_romanizer-0.1.12-cp38-abi3-macosx_11_0_arm64.whl | CPython 3.8 | abi3 | macOS 11.0+ ARM64 | Details |
| chord_romanizer-0.1.12-cp38-abi3-macosx_10_12_x86_64.whl | CPython 3.8 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 2.3 MB
Release files / chord_romanizer-0.1.12.tar.gz
| Download URL | chord_romanizer-0.1.12.tar.gz |
|---|---|
| Size | 143.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b8e455eef3a4415a8a4d4a95fa909a6cfe8212c30e505ba6c5a33fb2b42ebbc1
|
|
BLAKE2b-256 checksum How to use checksums |
86b7d3983b1fb2eb82772109b622930b0548cacb0226f77740c8d00e602f6175
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 29, 2026.
Transparency logRelease files / chord_romanizer-0.1.12-cp38-abi3-win_amd64.whl
| Download URL | chord_romanizer-0.1.12-cp38-abi3-win_amd64.whl |
|---|---|
| Size | 468.2 kB |
| Tags | CPython 3.8 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
084f7d7c2aa04e188cb8611ad25aa1576b767fe9a699d3a43f143d3bf2ed48d6
|
|
BLAKE2b-256 checksum How to use checksums |
96033e2e4d85592cdfc761274e43bfadddebf129b53174a7e84459b591d5bb25
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 29, 2026.
Transparency logRelease files / chord_romanizer-0.1.12-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | chord_romanizer-0.1.12-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 615.0 kB |
| Tags | CPython 3.8 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
c610ba887bff928d5757649109f33509372b4122bea1597d80b44849373a06a2
|
|
BLAKE2b-256 checksum How to use checksums |
4009e756db8a34ed2167fc415a407a7c6faa7bd09663f1381da01a9a39589e14
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 29, 2026.
Transparency logRelease files / chord_romanizer-0.1.12-cp38-abi3-macosx_11_0_arm64.whl
| Download URL | chord_romanizer-0.1.12-cp38-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 547.7 kB |
| Tags | CPython 3.8 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
657be616c4a4c470140b51e9f0333a9b93ea6daf66ee3409beb0902a56af871c
|
|
BLAKE2b-256 checksum How to use checksums |
bcecc846ad95ca1529fc158327a3b1656e16816343eec10c4d6e0f89710fd6d5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 29, 2026.
Transparency logRelease files / chord_romanizer-0.1.12-cp38-abi3-macosx_10_12_x86_64.whl
| Download URL | chord_romanizer-0.1.12-cp38-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 564.6 kB |
| Tags | CPython 3.8 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
9d02180893c3d587bcd599e43f4f596585680cfa397c4d6e52aa83d50c88b19b
|
|
BLAKE2b-256 checksum How to use checksums |
4d5fd3d1bceed7e58161e2df3b1ddbe4488f89a4900a7b67af7a134728800828
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 29, 2026.
Transparency log