A Grapheme-to-Phoneme converter (G2P) for the Qurʾan (Hafs riwaya), converting text to phoneme sequences with comprehensive support for all tajweed rules and waqf phonetic effects.
Project description
Qurʾanic Phonemizer
A Grapheme-to-Phoneme converter (G2P) for the Qurʾan (Hafs riwaya), converting text to phoneme sequences with comprehensive support for all tajweed rules and waqf phonetic effects.
Potential use cases:
- Speech Recognition: Phonetically transcribe recitations, create training data for machine learning systems
- Text-to-Speech: Develop accurate TTS systems for Qurʾanic Arabic
- Linguistic & Tajweed Analysis: Study phonological patterns and tajweed rule distributions across the Qurʾan, apply tajweed rule labels and coloring
- Educational Tools: Build interactive applications for assessing Qur'an and tajweed pronunciation
- Timing Analysis: Generate word-by-word timestamps for recitations, analyse madd/ghunnah durations
In addition to the Python API, the phonemizer can be used interactively: quranicphonemizer.com.
Table of Contents
- Phoneme Inventory
- Usage
- Input References
- Text Search
- Outputs
- Stops (Waqf)
- Contributing
- Credits
- Citing
Phoneme Inventory
The phoneme inventory uses the standard International Phonetic Alphabet (IPA) Arabic phonemes alongside custom phonemes for Tajweed rules, totalling 69-71 phonemes (depending on Tajweed configuration).
All phonemes are configurable in resources/base_phonemes.yaml and resources/rule_phonemes.yaml.
Consonants
| Letter | Phoneme | Letter | Phoneme | Letter | Phoneme | Letter | Phoneme |
|---|---|---|---|---|---|---|---|
| أ , إ , ء , ؤ , ئ | ʔ |
د | d / dd |
ض | dˤ / dˤdˤ |
ك | k / kk |
| ب | b / bb |
ذ | ð / ðð |
ط | tˤ / tˤtˤ |
ل | l / ll / lˤlˤ |
| ت | t / tt |
ر | r / rˤ / rr / rˤrˤ |
ظ | ðˤ / ðˤðˤ |
م | m |
| ث | θ / θθ |
ز | z / zz |
ع | ʕ / ʕʕ |
ن | n |
| ج | ʒ / ʒʒ |
س | s / ss |
غ | ɣ |
هـ | h / hh |
| ح | ħ / ħħ |
ش | ʃ / ʃʃ |
ف | f / ff |
و | w / ww |
| خ | x / xx |
ص | sˤ / sˤsˤ |
ق | q / qq |
ي , ى | j / jj |
Gemination (shaddah) is represented by repeating the phoneme to create new distinct phonemes. Note that there is no gemination for m / n (modelled as tajweed instead), and for ʔ / ɣ (do not exist in the Qurʾān).
Vowels
| Vowel | Phoneme |
|---|---|
| َ | a / aˤ |
| ُ | u |
| ِ | i |
| ا , ى | a: / aˤ: |
| و | u: |
| ي , ى | i: |
Tajweed Rules
| Rule | Phoneme |
|---|---|
| Iqlab | ŋ |
| Idgham | ñ / m̃ / j̃ / w̃ |
| Ikhfaa | ŋ (Light)ŋˤ (Heavy)ŋ (Shafawi) |
| Qalqala | Q (Sughra)QQ (Kubra) |
| Tafkheem | lˤlˤ (Lam in "Allah")rˤ / rˤrˤ (Raa) |
Usage
Installation
pip install quranic-phonemizer
Quick Start
from quranic_phonemizer import Phonemizer
pm = Phonemizer()
res = pm.phonemize("1:1")
print(res.text())
print(res.phonemes_str())
بِسْمِ ٱللَّهِ ٱلرَّحْمَـٰنِ ٱلرَّحِيمِ ١
bismi lla:hi rˤrˤaˤħma:ni rˤrˤaˤħi:m
Input References
phonemize() accepts a variety of flexible formats to specify which part of the Qurʾān to phonemize:
| Format Example | Meaning |
|---|---|
"1" |
Entire chapter 1 |
"1:1" |
Verse 1 of chapter 1 |
"1:1:1" |
Word 1 of verse 1 of chapter 1 |
"1:1 - 1:4" |
Verse range: 1:1 through 1:4 |
"1:1 - 1:2:2" |
From 1:1 to word 2 of 1:2 |
"1 - 2:2" |
From entire chapter 1 through verse 2 of chapter 2 |
Text Search
Instead of a reference, you can pass Arabic text directly using ref_text to fuzzy-match against the Uthmanic Hafs text of the Qur'an:
res = pm.phonemize(ref_text="بسم الله الرحمن الرحيم")
print(res.ref)
print(res.match_score)
print(res.phonemes_str())
1:1:1-1:1:4
0.903
bismi lla:hi rˤrˤaˤħma:ni rˤrˤaˤħi:m
The match_score attribute (0–1) indicates how closely the input text matched the Qurʾānic text. You can also scope the search to a specific surah or range by combining ref and ref_text:
res = pm.phonemize(ref="2", ref_text="الله لا إله إلا هو الحي القيوم")
print(res.ref)
print(res.match_score)
print(res.phonemes_str())
2:255:1-2:255:7
0.836
ʔalˤlˤaˤ:hu la: ʔila:ha ʔilla: huwa lħajju lqaˤjju:m
Outputs
phonemize() returns a PhonemizeResult object, containing:
| Attribute | Description |
|---|---|
ref |
The resolved reference string |
match_score |
Fuzzy match confidence (0–1) when using ref_text; None otherwise |
text() |
The Qurʾānic text |
phonemes_list(split) |
Phoneme lists grouped by split: "word", "verse", or "both" |
phonemes_str(phoneme_sep, word_sep, verse_sep) |
Full phoneme string, configurable with separators |
show_table(phoneme_sep, split) |
Pandas DataFrame view, grouped by split (requires pandas) |
save(path, *, fmt, split) |
Save results to JSON, CSV, or mapping format |
Output Example (Phonemes String)
res = pm.phonemize("112", stops=["verse"])
print(res.text())
print(res.phonemes_str(phoneme_sep=" ", word_sep=" | ", verse_sep="\n"))
قُلْ هُوَ ٱللَّهُ أَحَدٌ ١ ٱللَّهُ ٱلصَّمَدُ ٢ لَمْ يَلِدْ وَلَمْ يُولَدْ ٣ وَلَمْ يَكُن لَّهُۥ كُفُوًا أَحَدٌ ٤
q u l | h u w a | lˤlˤ aˤ: h u | ʔ a ħ a d Q | ʔ a lˤlˤ aˤ: h u | sˤsˤ aˤ m a d Q | l a m | j a l i d Q | w a l a m | j u: l a d Q | w a l a m | j a k u | ll a h u: | k u f u w a n | ʔ a ħ a d Q
Stops (Boundary Markers)
Optionally, pass a stops=[] list to force word/verse segmentation:
| Stop key | Symbol |
|---|---|
"verse" |
|
"preferred_continue" |
ۖ |
"preferred_stop" |
ۗ |
"optional_stop" |
ۚ |
"compulsory_stop" |
ۘ |
"prohibited_stop" |
ۙ |
ref = "68:33"
res = pm.phonemize(ref)
print(res.text())
print(res.phonemes_str())
res = pm.phonemize(ref, stops=["preferred_continue"])
print(res.phonemes_str())
res = pm.phonemize(ref, stops=["optional_stop"])
print(res.phonemes_str())
كَذَٰلِكَ ٱلْعَذَابُ ۖ وَلَعَذَابُ ٱلْـَٔاخِرَةِ أَكْبَرُ ۚ لَوْ كَانُوا۟ يَعْلَمُونَ ٣٣
kaða:lika lʕaða:bu walaʕaða:bu lʔa:xirˤaˤti ʔakbarˤu law ka:nu: jaʕlamu:n
kaða:lika lʕaða:bQ walaʕaða:bu lʔa:xirˤaˤti ʔakbarˤu law ka:nu: jaʕlamu:n
kaða:lika lʕaða:bu walaʕaða:bu lʔa:xirˤaˤti ʔakbarˤ law ka:nu: jaʕlamu:n
Contributing
If you find any issues or have feature suggestions, please feel free to open an issue or submit a pull request.
Future plans include detailed tajweed annotations and support for other turuq and riwayat.
Credits
The project makes use of the Quranic Universal Library's (QUL) Hafs script.
Citing
If you use this phonemizer in your work, please cite the paper as follows:
@inproceedings{
ibrahim2025quranic,
title={Qur{\textquoteright}anic Phonemizer: Bringing Tajweed-Aware Phonemes to Qur{\textquoteright}anic Machine Learning},
author={Ahmed Ibrahim},
booktitle={5th Muslims in ML Workshop co-located with NeurIPS 2025},
year={2025},
url={https://openreview.net/forum?id=hZt0JK28iV}
}
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file quranic_phonemizer-1.0.5.tar.gz.
File metadata
- Download URL: quranic_phonemizer-1.0.5.tar.gz
- Upload date:
- Size: 1.5 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0137ce20e9df5ce8a23ffc0fe99c283be1f51ba2405e173212d3bfd558fb1422
|
|
| MD5 |
4434852040e365927e3a40ab9ca246f7
|
|
| BLAKE2b-256 |
7f6757fa5814f33f1cd05b52a30b4d172fc6c86e4b1d5799e4ac812f5d976950
|
File details
Details for the file quranic_phonemizer-1.0.5-py3-none-any.whl.
File metadata
- Download URL: quranic_phonemizer-1.0.5-py3-none-any.whl
- Upload date:
- Size: 1.6 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0079608a08710fde4f56ae7667bab7632998a1890efa5b0daec6b54fb1f84a94
|
|
| MD5 |
b3757abc0479d4858194930815efbd1f
|
|
| BLAKE2b-256 |
5f928b9cbda575a877c4bcddf98df0c845eef452b8f308f95c05259ea0324864
|