@ghoran/audio 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. package/README.md +180 -150
  2. package/dist/abdulbasit-CgLk633T.mjs +14 -0
  3. package/dist/abdulbasit-DAE2X2re.mjs +12 -0
  4. package/dist/almuiqly-DcK4HlYB.mjs +12 -0
  5. package/dist/almuiqly-Ds8QVRUj.mjs +14 -0
  6. package/dist/ansarian-CsfxGgu4.mjs +14 -0
  7. package/dist/ansarian-DpNzQ_zn.mjs +93 -0
  8. package/dist/ayah-index-p8ffdA40.mjs +7 -0
  9. package/dist/catalog.d.ts +4 -0
  10. package/dist/catalog.mjs +31 -0
  11. package/dist/fooladvand-hedayatfar-CWQyHFBw.mjs +12 -0
  12. package/dist/fooladvand-hedayatfar-DPOvoFnl.mjs +14 -0
  13. package/dist/ghamadi-CTAKeToz.mjs +20 -0
  14. package/dist/ghamadi-Gq4oILyo.mjs +14 -0
  15. package/dist/hashes/abdulbasit.d.ts +5 -0
  16. package/dist/hashes/abdulbasit.mjs +7 -0
  17. package/dist/hashes/almuiqly.d.ts +5 -0
  18. package/dist/hashes/almuiqly.mjs +7 -0
  19. package/dist/hashes/ansarian.d.ts +5 -0
  20. package/dist/hashes/ansarian.mjs +7 -0
  21. package/dist/hashes/fooladvand-hedayatfar.d.ts +5 -0
  22. package/dist/hashes/fooladvand-hedayatfar.mjs +7 -0
  23. package/dist/hashes/ghamadi.d.ts +5 -0
  24. package/dist/hashes/ghamadi.mjs +7 -0
  25. package/dist/hashes/husary.d.ts +5 -0
  26. package/dist/hashes/husary.mjs +7 -0
  27. package/dist/hashes/jafarpour.d.ts +5 -0
  28. package/dist/hashes/jafarpour.mjs +7 -0
  29. package/dist/hashes/makarem-kabiri.d.ts +5 -0
  30. package/dist/hashes/makarem-kabiri.mjs +7 -0
  31. package/dist/hashes/maleki.d.ts +5 -0
  32. package/dist/hashes/maleki.mjs +7 -0
  33. package/dist/hashes/minshawy-mujawwad.d.ts +5 -0
  34. package/dist/hashes/minshawy-mujawwad.mjs +7 -0
  35. package/dist/hashes/minshawy-murattal.d.ts +5 -0
  36. package/dist/hashes/minshawy-murattal.mjs +7 -0
  37. package/dist/hashes/motaz.d.ts +5 -0
  38. package/dist/hashes/motaz.mjs +7 -0
  39. package/dist/hashes/parhizgar.d.ts +5 -0
  40. package/dist/hashes/parhizgar.mjs +7 -0
  41. package/dist/husary-58J-Hbbz.mjs +14 -0
  42. package/dist/husary-Bn_Cpg-n.mjs +12 -0
  43. package/dist/index-OUGKp8YA.d.ts +64 -0
  44. package/dist/index.d.ts +3 -0
  45. package/dist/index.mjs +16 -0
  46. package/dist/jafarpour-2Nco5LM6.mjs +14 -0
  47. package/dist/jafarpour-DhxbJtKc.mjs +12 -0
  48. package/dist/load.d.ts +10 -0
  49. package/dist/load.mjs +114 -0
  50. package/dist/makarem-kabiri-DgUm5g8A.mjs +12 -0
  51. package/dist/makarem-kabiri-Di0qt0pO.mjs +14 -0
  52. package/dist/maleki-BtTzBMIi.mjs +14 -0
  53. package/dist/maleki-DLwnRVZB.mjs +2433 -0
  54. package/dist/math-CqmOaUpt.mjs +9 -0
  55. package/dist/minshawy-mujawwad-CF0_Aws9.mjs +14 -0
  56. package/dist/minshawy-mujawwad-DZAV9x0T.mjs +12 -0
  57. package/dist/minshawy-murattal-B3IrUpMY.mjs +12 -0
  58. package/dist/minshawy-murattal-DWTJ7Vbi.mjs +14 -0
  59. package/dist/motaz-BPiSDPjo.mjs +14 -0
  60. package/dist/motaz-D8LZxwly.mjs +333 -0
  61. package/dist/pair.d.ts +52 -0
  62. package/dist/pair.mjs +83 -0
  63. package/dist/paired/abdulbasit.d.ts +5 -0
  64. package/dist/paired/abdulbasit.mjs +6 -0
  65. package/dist/paired/almuiqly.d.ts +5 -0
  66. package/dist/paired/almuiqly.mjs +6 -0
  67. package/dist/paired/ansarian.d.ts +5 -0
  68. package/dist/paired/ansarian.mjs +6 -0
  69. package/dist/paired/fooladvand-hedayatfar.d.ts +5 -0
  70. package/dist/paired/fooladvand-hedayatfar.mjs +6 -0
  71. package/dist/paired/ghamadi.d.ts +5 -0
  72. package/dist/paired/ghamadi.mjs +6 -0
  73. package/dist/paired/husary.d.ts +5 -0
  74. package/dist/paired/husary.mjs +6 -0
  75. package/dist/paired/jafarpour.d.ts +5 -0
  76. package/dist/paired/jafarpour.mjs +6 -0
  77. package/dist/paired/makarem-kabiri.d.ts +5 -0
  78. package/dist/paired/makarem-kabiri.mjs +6 -0
  79. package/dist/paired/maleki.d.ts +5 -0
  80. package/dist/paired/maleki.mjs +6 -0
  81. package/dist/paired/minshawy-mujawwad.d.ts +5 -0
  82. package/dist/paired/minshawy-mujawwad.mjs +6 -0
  83. package/dist/paired/minshawy-murattal.d.ts +5 -0
  84. package/dist/paired/minshawy-murattal.mjs +6 -0
  85. package/dist/paired/motaz.d.ts +5 -0
  86. package/dist/paired/motaz.mjs +6 -0
  87. package/dist/paired/parhizgar.d.ts +5 -0
  88. package/dist/paired/parhizgar.mjs +6 -0
  89. package/dist/parhizgar-CbOhvNfy.mjs +12 -0
  90. package/dist/parhizgar-DI28CJpf.mjs +14 -0
  91. package/dist/playback-CeKsQsxV.mjs +123 -0
  92. package/dist/sources/abdulbasit.d.ts +2 -0
  93. package/dist/sources/abdulbasit.mjs +1 -0
  94. package/dist/sources/almuiqly.d.ts +2 -0
  95. package/dist/sources/almuiqly.mjs +1 -0
  96. package/dist/sources/ansarian.d.ts +2 -0
  97. package/dist/sources/ansarian.mjs +1 -0
  98. package/dist/sources/fooladvand-hedayatfar.d.ts +2 -0
  99. package/dist/sources/fooladvand-hedayatfar.mjs +1 -0
  100. package/dist/sources/ghamadi.d.ts +2 -0
  101. package/dist/sources/ghamadi.mjs +1 -0
  102. package/dist/sources/husary.d.ts +2 -0
  103. package/dist/sources/husary.mjs +1 -0
  104. package/dist/sources/jafarpour.d.ts +2 -0
  105. package/dist/sources/jafarpour.mjs +1 -0
  106. package/dist/sources/makarem-kabiri.d.ts +2 -0
  107. package/dist/sources/makarem-kabiri.mjs +1 -0
  108. package/dist/sources/maleki.d.ts +2 -0
  109. package/dist/sources/maleki.mjs +1 -0
  110. package/dist/sources/minshawy-mujawwad.d.ts +2 -0
  111. package/dist/sources/minshawy-mujawwad.mjs +1 -0
  112. package/dist/sources/minshawy-murattal.d.ts +2 -0
  113. package/dist/sources/minshawy-murattal.mjs +1 -0
  114. package/dist/sources/motaz.d.ts +2 -0
  115. package/dist/sources/motaz.mjs +1 -0
  116. package/dist/sources/parhizgar.d.ts +2 -0
  117. package/dist/sources/parhizgar.mjs +1 -0
  118. package/dist/targets/-16/abdulbasit.d.ts +5 -0
  119. package/dist/targets/-16/abdulbasit.mjs +333 -0
  120. package/dist/targets/-16/almuiqly.d.ts +5 -0
  121. package/dist/targets/-16/almuiqly.mjs +3953 -0
  122. package/dist/targets/-16/ansarian.d.ts +5 -0
  123. package/dist/targets/-16/ansarian.mjs +29723 -0
  124. package/dist/targets/-16/fooladvand-hedayatfar.d.ts +5 -0
  125. package/dist/targets/-16/fooladvand-hedayatfar.mjs +13818 -0
  126. package/dist/targets/-16/ghamadi.d.ts +5 -0
  127. package/dist/targets/-16/ghamadi.mjs +2133 -0
  128. package/dist/targets/-16/husary.d.ts +5 -0
  129. package/dist/targets/-16/husary.mjs +7958 -0
  130. package/dist/targets/-16/jafarpour.d.ts +5 -0
  131. package/dist/targets/-16/jafarpour.mjs +9243 -0
  132. package/dist/targets/-16/makarem-kabiri.d.ts +5 -0
  133. package/dist/targets/-16/makarem-kabiri.mjs +24293 -0
  134. package/dist/targets/-16/maleki.d.ts +5 -0
  135. package/dist/targets/-16/maleki.mjs +23403 -0
  136. package/dist/targets/-16/minshawy-mujawwad.d.ts +5 -0
  137. package/dist/targets/-16/minshawy-mujawwad.mjs +38 -0
  138. package/dist/targets/-16/minshawy-murattal.d.ts +5 -0
  139. package/dist/targets/-16/minshawy-murattal.mjs +108 -0
  140. package/dist/targets/-16/motaz.d.ts +5 -0
  141. package/dist/targets/-16/motaz.mjs +7813 -0
  142. package/dist/targets/-16/parhizgar.d.ts +5 -0
  143. package/dist/targets/-16/parhizgar.mjs +183 -0
  144. package/dist/targets/-18/abdulbasit.d.ts +5 -0
  145. package/dist/targets/-18/abdulbasit.mjs +12 -0
  146. package/dist/targets/-18/almuiqly.d.ts +5 -0
  147. package/dist/targets/-18/almuiqly.mjs +73 -0
  148. package/dist/targets/-18/ansarian.d.ts +5 -0
  149. package/dist/targets/-18/ansarian.mjs +16483 -0
  150. package/dist/targets/-18/fooladvand-hedayatfar.d.ts +5 -0
  151. package/dist/targets/-18/fooladvand-hedayatfar.mjs +1308 -0
  152. package/dist/targets/-18/ghamadi.d.ts +5 -0
  153. package/dist/targets/-18/ghamadi.mjs +248 -0
  154. package/dist/targets/-18/husary.d.ts +5 -0
  155. package/dist/targets/-18/husary.mjs +12 -0
  156. package/dist/targets/-18/jafarpour.d.ts +5 -0
  157. package/dist/targets/-18/jafarpour.mjs +233 -0
  158. package/dist/targets/-18/makarem-kabiri.d.ts +5 -0
  159. package/dist/targets/-18/makarem-kabiri.mjs +2873 -0
  160. package/dist/targets/-18/maleki.d.ts +5 -0
  161. package/dist/targets/-18/maleki.mjs +11178 -0
  162. package/dist/targets/-18/minshawy-mujawwad.d.ts +5 -0
  163. package/dist/targets/-18/minshawy-mujawwad.mjs +12 -0
  164. package/dist/targets/-18/minshawy-murattal.d.ts +5 -0
  165. package/dist/targets/-18/minshawy-murattal.mjs +12 -0
  166. package/dist/targets/-18/motaz.d.ts +5 -0
  167. package/dist/targets/-18/motaz.mjs +1978 -0
  168. package/dist/targets/-18/parhizgar.d.ts +5 -0
  169. package/dist/targets/-18/parhizgar.mjs +12 -0
  170. package/dist/targets/-23/abdulbasit.d.ts +5 -0
  171. package/dist/targets/-23/abdulbasit.mjs +12 -0
  172. package/dist/targets/-23/almuiqly.d.ts +5 -0
  173. package/dist/targets/-23/almuiqly.mjs +12 -0
  174. package/dist/targets/-23/ansarian.d.ts +5 -0
  175. package/dist/targets/-23/ansarian.mjs +12 -0
  176. package/dist/targets/-23/fooladvand-hedayatfar.d.ts +5 -0
  177. package/dist/targets/-23/fooladvand-hedayatfar.mjs +12 -0
  178. package/dist/targets/-23/ghamadi.d.ts +5 -0
  179. package/dist/targets/-23/ghamadi.mjs +20 -0
  180. package/dist/targets/-23/husary.d.ts +5 -0
  181. package/dist/targets/-23/husary.mjs +12 -0
  182. package/dist/targets/-23/jafarpour.d.ts +5 -0
  183. package/dist/targets/-23/jafarpour.mjs +12 -0
  184. package/dist/targets/-23/makarem-kabiri.d.ts +5 -0
  185. package/dist/targets/-23/makarem-kabiri.mjs +12 -0
  186. package/dist/targets/-23/maleki.d.ts +5 -0
  187. package/dist/targets/-23/maleki.mjs +16 -0
  188. package/dist/targets/-23/minshawy-mujawwad.d.ts +5 -0
  189. package/dist/targets/-23/minshawy-mujawwad.mjs +12 -0
  190. package/dist/targets/-23/minshawy-murattal.d.ts +5 -0
  191. package/dist/targets/-23/minshawy-murattal.mjs +12 -0
  192. package/dist/targets/-23/motaz.d.ts +5 -0
  193. package/dist/targets/-23/motaz.mjs +16 -0
  194. package/dist/targets/-23/parhizgar.d.ts +5 -0
  195. package/dist/targets/-23/parhizgar.mjs +12 -0
  196. package/dist/types-BiTocnkC.d.ts +76 -0
  197. package/dist/url.d.ts +5 -0
  198. package/dist/url.mjs +135 -0
  199. package/dist/verify.d.ts +7 -0
  200. package/dist/verify.mjs +26 -0
  201. package/package.json +11 -10
package/README.md CHANGED
@@ -1,150 +1,180 @@
1
- # @ghoran/audio
2
-
3
- پروفایل‌های کم‌حجم و Tree-shakable برای هماهنگی بلندی تلاوت و ترجمهٔ صوتی قرآن؛ بدون وابستگی اجرایی، دریافت صوت، Decode، تحلیل لحظه‌ای یا کنترل پلیر.
4
-
5
- ## نسخهٔ مرجع فعلی
6
-
7
- این snapshot شامل ۸۱٬۰۶۸ فایل قابل Decode و دارای Gain است؛ ۱۰ فایل خراب و یک فایل بسیار کوتاه با ۱۱ نسخهٔ جایگزین پذیرفته‌شده توسط کاربر رفع شده‌اند. سابقهٔ قبلی حفظ شده است. این پذیرش، تأیید مستقل شنیداریِ متن یا مرزها نیست.
8
-
9
- **انتشار این ۱۱ نسخه در URLهای اصلی هنوز تأیید نشده است.** `audioDataset.pendingPublicationFiles` جمع آن‌ها و `profile.metadata.pendingPublicationFiles` تعداد هر منبع را نشان می‌دهد. تا جایگزینی بایت‌های CDN و پاک‌شدن cache قدیمی، Gain جدید فقط برای همان فایل مرجع جدید معتبر است. مسیر `/verify` هش قدیمی را رد می‌کند. نبود Gain در snapshot فعلی صفر است، ولی API همچنان برای نسخهٔ نامعتبر/ناشناخته یا هش نامنطبق `null` را حفظ می‌کند. هشدارهای آماری باقی‌مانده مستقل از این اصلاح‌ها هستند.
10
-
11
- ## شروع سریع
12
-
13
- ```ts
14
- import { parhizgar, ansarian } from '@ghoran/audio'
15
-
16
- const ayahIndex = 261 // بقره، آیهٔ ۲۵۵؛ همان اندیس متن و Ayah.index
17
- const gain = parhizgar.getGain(ayahIndex) // ضریب خطی آماده، با حفاظت Peak
18
- const translationGain = ansarian.getGain(ayahIndex)
19
-
20
- if (gain !== null) {
21
- // مقدار آماده را به کنترل Gain پلیر خود بدهید.
22
- }
23
- ```
24
-
25
- هر منبع فقط متادیتا و استثناهای خودش را دارد. import نام‌دارِ بالا توسط bundler قابل Tree Shaking است. برای مرزبندی صریح‌تر، ورودی مستقل نیز وجود دارد:
26
-
27
- ```ts
28
- import parhizgar from '@ghoran/audio/sources/parhizgar'
29
- import ansarian from '@ghoran/audio/sources/ansarian'
30
- ```
31
-
32
- ورودی اصلی هیچ catalog سراسری، manifest هش، loader پویا یا اندازه‌گیری پژوهشی را وارد مسیر پخش نمی‌کند. بیلد مصرف‌کنندهٔ واقعی، نبود متادیتای ۱۱ منبع دیگر، سایر سیاست‌ها و دادهٔ SHA-256 را برای این مثال بررسی می‌کند. ورود namespace و استفادهٔ پویا از همهٔ exportها می‌تواند مانع حذف منابع شود؛ برای پروژه با منابع ثابت، named import یا subpath مناسب است.
33
-
34
- ## API هر منبع
35
-
36
- | API | خروجی |
37
- | -------------------------------------- | ----------------------------------------------------------------- |
38
- | `profile.getGain(ayahIndex)` | ضریب دامنهٔ نهایی یا `null` |
39
- | `profile.getGainDb(ayahIndex)` | Gain نهایی برحسب dB یا `null` |
40
- | `profile.getRecommendation(ayahIndex)` | وضعیت، علت نبود Gain، حفاظت Peak و نسخهٔ داده |
41
- | `profile.metadata` | نام، نوع، baseline، تعداد اندازه‌گیری و contentRevision همان منبع |
42
- | `profile.policy` | هدف، سقف Peak، حاشیه و حدود افزایش/کاهش |
43
-
44
- تمام APIهای آیه از **اندیس صفرمبنا، از ۰ تا ۶۲۳۵** استفاده می‌کنند؛ دقیقاً همان اندیس آرایهٔ متن، ترجمه و `Ayah.index`. عدد یک‌مبنا، رشته و آبجکت آدرس پشتیبانی نمی‌شوند. اندیس نامعتبر `RangeError` می‌دهد؛ اندازه‌گیری نامعتبر یا ناموجود `null` می‌دهد. `null` را با `1` یا Gain پایه جایگزین نکنید.
45
-
46
- ```ts
47
- parhizgar.getGain(0) // فاتحه ۱
48
- parhizgar.getGain(261) // بقره ۲۵۵
49
- parhizgar.getGain(6235) // ناس ۶
50
- ```
51
-
52
- `getRecommendation` همان `ayahIndex` ورودی را برمی‌گرداند؛ برای تولید جزئیات Gain هیچ تبدیل سوره/آیه انجام نمی‌شود. دادهٔ runtime همچنان **Gain پایه + استثناهای کم‌تعداد** است و آرایهٔ ۶۲۳۶تایی Gain برای هر منبع نگهداری نمی‌شود.
53
-
54
- ### URL اختیاری
55
-
56
- کد تبدیل اندیس به نام فایل و جدول ۱۱۴ سوره فقط از ورودی مستقل `/url` وارد می‌شوند؛ پروفایل‌ها و registry متد `getUrl` ندارند. در برنامه‌ای که URL خودش را دارد، این ورودی را import نکنید:
57
-
58
- ```ts
59
- import { getAudioUrl } from '@ghoran/audio/url'
60
-
61
- const url = getAudioUrl(parhizgar, 261) // .../002255.mp3
62
- // metadata انتخاب‌شده از /catalog نیز پذیرفته می‌شود.
63
- ```
64
-
65
- این تابع دریافت فایل یا تأیید محتوای URL انجام نمی‌دهد. اگر آدرس سوره/آیه دارید، می‌توانید با `Ayah.getByKey('2:255')!.index` از `@ghoran/entity` اندیس مشترک بگیرید؛ پکیج صوت برای Gain به آن پکیج وابسته نیست.
66
-
67
- برای lookup با شناسهٔ منبع فقط منابع مورد استفاده را ثبت کنید:
68
-
69
- ```ts
70
- import { createAudioNormalizer, parhizgar, ansarian } from '@ghoran/audio'
71
-
72
- const audio = createAudioNormalizer({ sources: [parhizgar, ansarian] })
73
- const gain = audio.getGain('parhizgar', 261)
74
- const details = audio.getRecommendation('ansarian', 261)
75
- ```
76
-
77
- TypeScript شناسه‌ها را به منابع ثبت‌شده محدود می‌کند. منبع تکراری، هدف متفاوت یا snapshot ناسازگار پذیرفته نمی‌شود. lookup همگام است و هیچ I/O ندارد. ضرایب خطی پس از آماده‌سازی هر منبع cache می‌شوند؛ هیچ ضرب نمونه‌ای توسط این کتابخانه اجرا نمی‌شود.
78
-
79
- ## سیاست‌های دیگر؛ فقط در صورت import
80
-
81
- ورودی پیش‌فرض هر منبع، سیاست **‎−۲۰ LUFS** است. برای ‎−۲۳، ‎−۱۸ و ‎−۱۶، فقط همان منبع و سیاست را import کنید:
82
-
83
- ```ts
84
- import parhizgar from '@ghoran/audio/targets/-23/parhizgar'
85
- import ansarian from '@ghoran/audio/targets/-23/ansarian'
86
- ```
87
-
88
- برای اپ با انتخاب پویا، loader اختیاری وجود دارد:
89
-
90
- ```ts
91
- import { loadAudioSource } from '@ghoran/audio/load'
92
-
93
- const profile = await loadAudioSource('parhizgar', { targetLufs: -20 })
94
- const gain = profile.getGain(0)
95
- ```
96
-
97
- مسیر `/load` در bundler می‌تواند chunkهای جداگانهٔ تمام گزینه‌های قابل انتخاب را **تولید** کند؛ فقط گزینهٔ درخواست‌شده را **بارگیری** می‌کند. برای حذف کامل سایر منابع از خروجی پروژه، ورودی‌های ثابت را به کار ببرید. فهرست منابع برای UI انتخاب قاری، جداست:
98
-
99
- ```ts
100
- import { audioSources } from '@ghoran/audio/catalog'
101
- ```
102
-
103
- ## حفاظت Peak و حفظ اصالت
104
-
105
- سیاست فعلی Gain پایهٔ مجموعه را همراه با حفاظت True Peak اعمال می‌کند. اصلاح بخش ضبط و outlier استنباطی خودکار اعمال نمی‌شود. کل فایل یک Gain ثابت دارد؛ دامنهٔ طبیعی داخل آیه صاف نمی‌شود. هیچ MP3 تغییر یا دوباره Encode نشده است.
106
-
107
- سقف True Peak برابر ‎−۱ dBTP و حاشیهٔ اضافی ۰٫۱۵ dB است. افزایش حداکثر ۸ و کاهش حداکثر ۱۸ dB است. Gain به گام‌های **۰٫۰۱ dB به سمت مقدار کمتر** تبدیل می‌شود؛ اختلاف از توصیهٔ دقیق کمتر از ۰٫۰۱ dB است و حفاظت Peak با عدد نهایی بررسی می‌شود. برای مثال Gain پایهٔ ‎−۷٫۵۳۳ به ‎−۷٫۵۴ تبدیل می‌شود. دقت ثابت، تعداد مقادیر و حجم داده را کاهش می‌دهد.
108
-
109
- LUFS هدف، baseline مجموعه است؛ قرار نیست هر آیه به ‎−۲۰ برسد. اعداد بر قرارداد پخش مونو با کپی دامنهٔ یکسان به هر دو کانال تکیه دارند. در pan-law دیگر، توصیه‌ها نیاز به بازتولید دارند. جمع چند صوت هم‌زمان و تقویت دیگری پس از این Gain، به headroom جدا نیاز دارد.
110
-
111
- ## تطبیق با نسخهٔ واقعی صوت
112
-
113
- `getGain` یک lookup روی **صوت مرجع اندازه‌گیری‌شده** است؛ تغییر محتوای URL ثابت را تشخیص نمی‌دهد. `snapshotId` و `contentRevision` شناسهٔ نسخه‌اند و به‌تنهایی اثبات تطابق بایت‌های فایل نیستند. در `getRecommendation` مقدار `contentVerified` صریحاً `false` است.
114
-
115
- برای مسیر سخت‌گیرانه، فقط manifest هش همان منبع را وارد کنید و SHA-256 واقعی فایل دریافت‌شده را بدهید:
116
-
117
- ```ts
118
- import parhizgar from '@ghoran/audio/sources/parhizgar'
119
- import hashes from '@ghoran/audio/hashes/parhizgar'
120
- import { getVerifiedAudioGain } from '@ghoran/audio/verify'
121
-
122
- const gain = getVerifiedAudioGain(parhizgar, hashes, 261, actualAudioSha256)
123
- // محتوای تغییرکرده، revision ناسازگار یا Gain ناموجود -> null
124
- ```
125
-
126
- هش از بایت‌های فایل اصلی است، نه PCM Decodeشده. محاسبهٔ هش را می‌توانید یک بار در مسیر دانلود/cache انجام دهید. کتابخانه صوت را دوباره دریافت نمی‌کند و WebCrypto/DOM/Node API در runtime لازم ندارد. manifest هش عمداً از دادهٔ Gain بزرگ‌تر و کاملاً اختیاری است. برای بارگیری پویا از `loadAudioContentManifest` در `/load` استفاده کنید.
127
-
128
- ## منابع و وضعیت داده
129
-
130
- شناسه‌ها: `parhizgar`, `ghamadi`, `husary`, `minshawy-murattal`, `minshawy-mujawwad`, `motaz`, `abdulbasit`, `almuiqly`, `jafarpour`, `ansarian`, `maleki`, `makarem-kabiri`, `fooladvand-hedayatfar`.
131
-
132
- exportهای نام‌دار دوکلمه‌ای camelCase هستند: `minshawyMurattal`, `minshawyMujawwad`, `makaremKabiri`, `fooladvandHedayatfar`. subpath همیشه شناسهٔ اصلی خط‌تیره‌دار را دارد.
133
-
134
- فهرست کامل ۸۱٬۰۶۸ مورد بررسی شده است؛ snapshot مرجع فعلی پس از پذیرش جایگزین‌ها برای همهٔ موارد Gain دارد. انتشار ۱۱ جایگزین در URL اصلی همچنان تأیید نشده است. موفقیت Decode، صحت محتوای آیه یا انتساب قاری را ثابت نمی‌کند. ۱۱۲ URL معیقلی برخلاف پسوند mp3 محتوای PCM دارند؛ انتخاب decoder باید از روی محتوای واقعی انجام شود.
135
-
136
- ## توسعه و بازتولید
137
-
138
- دادهٔ Measured، Inferred و Recommended کامل در پوشه‌های `analysis/` و `data/` **مخزن Git** و آرشیو مستقل نگهداری می‌شود؛ فایل‌های حجیم پژوهشی در بستهٔ npm نیستند. `/profiles` ورود اختیاری پروفایل‌های استنباطی است. دادهٔ خام `/data/*` از بستهٔ نصب‌شدنی صادر نمی‌شود.
139
-
140
- ```sh
141
- pnpm --filter @ghoran/audio generate:runtime
142
- pnpm --filter @ghoran/audio check:runtime
143
- pnpm --filter @ghoran/audio build
144
- pnpm test
145
- pnpm check:packages
146
- ```
147
-
148
- کامپایلر Node از snapshot متعهدشدهٔ داده، بدون Python، FFmpeg یا شبکه، ورودی‌های مستقل هر منبع و سیاست را بازتولید می‌کند. هش ورودی‌ها، شمار رکوردها، تطابق توصیه‌ها، حدود Gain و سقف Peak را برای تمام ۳۲۴٬۲۷۲ ترکیب منبع/آیه/هدف بررسی می‌کند. اختلاف با سیاست baseline-only باعث شکست بیلد می‌شود؛ اصلاح‌های استنباطی تأییدشدهٔ احتمالی آینده بدون تغییر صریح این قرارداد وارد runtime نمی‌شوند.
149
-
150
- کد تحت MIT؛ ساختار سوره و آیه از [Tanzil Project](https://tanzil.net/docs/Quran_Metadata) است؛ snapshot و attribution کامل آن نیز در مخزن حفظ شده‌اند. صوت‌های اصلی داخل npm یا آرشیو تحلیل توزیع نمی‌شوند.
1
+ # @ghoran/audio
2
+
3
+ پروفایل‌های کم‌حجم و Tree-shakable برای هماهنگی بلندی تلاوت و ترجمهٔ صوتی قرآن؛ بدون وابستگی اجرایی، دریافت صوت، Decode، تحلیل لحظه‌ای یا کنترل پلیر.
4
+
5
+
6
+ ## توازن همان آیه و ترجمه — نسخهٔ ۰٫۳
7
+
8
+ Gain پایهٔ مجموعه، اختلافِ تک‌تک جفت‌ها را تضمین نمی‌کند: در روش قبلی، ترجمهٔ ملکی در فاتحهٔ ۱ حدود **۱۱٫۳ LU** بلندتر از معتز باقی می‌ماند. برای پخش پشت‌سرهم، از API اختیاریِ توازن استفاده کنید:
9
+
10
+ ```ts
11
+ import motaz from '@ghoran/audio/paired/motaz'
12
+ import maleki from '@ghoran/audio/paired/maleki'
13
+ import { createAudioPair } from '@ghoran/audio/pair'
14
+
15
+ const audio = createAudioPair({ recitation: motaz, translation: maleki })
16
+ const result = audio.getRecommendation(ayahIndex)
17
+ if (result.status === 'ready') {
18
+ recitationGainNode.gain.value = result.recitation.gainLinear
19
+ translationGainNode.gain.value = result.translation.gainLinear
20
+ // matched / cutLimited / differenceLu نشان می‌دهند هدف دست‌یافتنی بوده یا خیر.
21
+ }
22
+ ```
23
+
24
+ این حالت ابتدا Gain پایه و حفاظت Peak را می‌گیرد، سپس **فقط عضو بلندتر همان جفت را کاهش** می‌دهد تا اختلافِ پیش‌بینی‌شده حداکثر ۱ LU شود. فایل آرام‌تر، سطح قابل دستیابی را تعیین می‌کند؛ قرار نیست همهٔ آیات یکسان یا حتماً ‎−۲۰ LUFS شوند. هیچ تقویت اضافه، limiter، compressor، تغییر سکوت یا DSP لحظه‌ای انجام نمی‌شود. Gain کل هر فایل ثابت است، پس دینامیک داخل فایل حفظ می‌شود؛ **دینامیک بین فایل‌ها تغییر می‌کند**. این سیاست انتخابیِ پخش است، نه اعلام خطا یا اصلاح خودکار فرضیه‌های ضبط.
25
+
26
+ `toleranceLu` پیش‌فرض ۱ و `maximumAdditionalCutDb` پیش‌فرض ۱۸ است؛ سقف مطلق کاهش پروفایل نیز رعایت می‌شود. کمبود بودجه با `matched: false` و `cutLimited: true` مشخص می‌شود. دادهٔ نامعتبر `status: 'unavailable'` و خروجی‌های `null` می‌دهد؛ چیزی از همسایه حدس زده نمی‌شود.
27
+
28
+ ورودی‌های `/sources/*` همچنان **Gain پایه + استثناها** هستند. فقط `/paired/*` علاوه بر آن، ۶٬۲۳۶ اندازه‌گیری بلندی پخش را با دقت ۰٫۱ LU نگه می‌دارد: ۱۲٬۴۷۲ بایت باینری برای هر منبع، حدود ۸ KB فشرده در ماژول منتشرشده. این داده آرایهٔ Gain نیست و مستقل از سیاست جفت است. فقط منابع importشده وارد باندل می‌شوند؛ جدول آدرس، هش‌ها و سایر قاریان وارد نمی‌شوند. خطای اختلاف ناشی از کوانتیزه‌کردن حداکثر ۰٫۱ LU است. نزدیک‌شدن LUFS، برابری کامل ادراک، رنگ صدا یا دینامیک را تضمین نمی‌کند.
29
+
30
+ در ممیزی تمام **۲۲۴٬۴۹۶ جفت مرجع**، ۱۳۰ جفت با سقف کاهش قابل تطبیق کامل نبودند. برای معتز–ملکی، صدک ۹۵ اختلاف از ۵٫۲۵ به ۱٫۰۶ LU و بیشینه از ۱۱٫۵۰ به ۱٫۱۰ LU رسید؛ این‌ها **پیش‌بینی از اندازه‌گیری مرجع** هستند، نه آزمون شنیداری. [گزارش و روش بازتولید](https://github.com/sabereen/ghoran/blob/main/packages/audio/RESEARCH.md) تفکیک دادهٔ خام، پیش‌بینی و اندازه‌گیری مجدد را توضیح می‌دهد.
31
+
32
+ این API هم بایتِ در حال پخش را تأیید نمی‌کند (`contentVerified: false`). برای تطبیق سخت‌گیرانه، هش **هر دو فایل اصلی** را با manifest همان منبع بررسی کنید. برای بخش کوتاه‌شدهٔ آیه، اندازه‌گیریِ کل آیه لزوماً بلندی همان بخش نیست.
33
+
34
+ ## نسخهٔ مرجع فعلی
35
+
36
+ این snapshot شامل ۸۱٬۰۶۸ فایل قابل Decode و دارای Gain است؛ ۱۰ فایل خراب و یک فایل بسیار کوتاه با ۱۱ نسخهٔ جایگزین پذیرفته‌شده توسط کاربر رفع شده‌اند. سابقهٔ قبلی حفظ شده است. این پذیرش، تأیید مستقل شنیداریِ متن یا مرزها نیست.
37
+
38
+ **انتشار این ۱۱ نسخه در URLهای اصلی هنوز تأیید نشده است.** `audioDataset.pendingPublicationFiles` جمع آن‌ها و `profile.metadata.pendingPublicationFiles` تعداد هر منبع را نشان می‌دهد. تا جایگزینی بایت‌های CDN و پاک‌شدن cache قدیمی، Gain جدید فقط برای همان فایل مرجع جدید معتبر است. مسیر `/verify` هش قدیمی را رد می‌کند. نبود Gain در snapshot فعلی صفر است، ولی API همچنان برای نسخهٔ نامعتبر/ناشناخته یا هش نامنطبق `null` را حفظ می‌کند. هشدارهای آماری باقی‌مانده مستقل از این اصلاح‌ها هستند.
39
+
40
+ ## شروع سریع
41
+
42
+ ```ts
43
+ import { parhizgar, ansarian } from '@ghoran/audio'
44
+
45
+ const ayahIndex = 261 // بقره، آیهٔ ۲۵۵؛ همان اندیس متن و Ayah.index
46
+ const gain = parhizgar.getGain(ayahIndex) // ضریب خطی آماده، با حفاظت Peak
47
+ const translationGain = ansarian.getGain(ayahIndex)
48
+
49
+ if (gain !== null) {
50
+ // مقدار آماده را به کنترل Gain پلیر خود بدهید.
51
+ }
52
+ ```
53
+
54
+ هر منبع فقط متادیتا و استثناهای خودش را دارد. import نام‌دارِ بالا توسط bundler قابل Tree Shaking است. برای مرزبندی صریح‌تر، ورودی مستقل نیز وجود دارد:
55
+
56
+ ```ts
57
+ import parhizgar from '@ghoran/audio/sources/parhizgar'
58
+ import ansarian from '@ghoran/audio/sources/ansarian'
59
+ ```
60
+
61
+ ورودی اصلی هیچ catalog سراسری، manifest هش، loader پویا یا اندازه‌گیری پژوهشی را وارد مسیر پخش نمی‌کند. بیلد مصرف‌کنندهٔ واقعی، نبود متادیتای ۱۱ منبع دیگر، سایر سیاست‌ها و دادهٔ SHA-256 را برای این مثال بررسی می‌کند. ورود namespace و استفادهٔ پویا از همهٔ exportها می‌تواند مانع حذف منابع شود؛ برای پروژه با منابع ثابت، named import یا subpath مناسب است.
62
+
63
+ ## API هر منبع
64
+
65
+ | API | خروجی |
66
+ | -------------------------------------- | ----------------------------------------------------------------- |
67
+ | `profile.getGain(ayahIndex)` | ضریب دامنهٔ نهایی یا `null` |
68
+ | `profile.getGainDb(ayahIndex)` | Gain نهایی برحسب dB یا `null` |
69
+ | `profile.getRecommendation(ayahIndex)` | وضعیت، علت نبود Gain، حفاظت Peak و نسخهٔ داده |
70
+ | `profile.metadata` | نام، نوع، baseline، تعداد اندازه‌گیری و contentRevision همان منبع |
71
+ | `profile.policy` | هدف، سقف Peak، حاشیه و حدود افزایش/کاهش |
72
+
73
+ تمام APIهای آیه از **اندیس صفرمبنا، از ۰ تا ۶۲۳۵** استفاده می‌کنند؛ دقیقاً همان اندیس آرایهٔ متن، ترجمه و `Ayah.index`. عدد یک‌مبنا، رشته و آبجکت آدرس پشتیبانی نمی‌شوند. اندیس نامعتبر `RangeError` می‌دهد؛ اندازه‌گیری نامعتبر یا ناموجود `null` می‌دهد. `null` را با `1` یا Gain پایه جایگزین نکنید.
74
+
75
+ ```ts
76
+ parhizgar.getGain(0) // فاتحه ۱
77
+ parhizgar.getGain(261) // بقره ۲۵۵
78
+ parhizgar.getGain(6235) // ناس ۶
79
+ ```
80
+
81
+ `getRecommendation` همان `ayahIndex` ورودی را برمی‌گرداند؛ برای تولید جزئیات Gain هیچ تبدیل سوره/آیه انجام نمی‌شود. دادهٔ runtime همچنان **Gain پایه + استثناهای کم‌تعداد** است و آرایهٔ ۶۲۳۶تایی Gain برای هر منبع نگهداری نمی‌شود.
82
+
83
+ ### URL اختیاری
84
+
85
+ کد تبدیل اندیس به نام فایل و جدول ۱۱۴ سوره فقط از ورودی مستقل `/url` وارد می‌شوند؛ پروفایل‌ها و registry متد `getUrl` ندارند. در برنامه‌ای که URL خودش را دارد، این ورودی را import نکنید:
86
+
87
+ ```ts
88
+ import { getAudioUrl } from '@ghoran/audio/url'
89
+
90
+ const url = getAudioUrl(parhizgar, 261) // .../002255.mp3
91
+ // metadata انتخاب‌شده از /catalog نیز پذیرفته می‌شود.
92
+ ```
93
+
94
+ این تابع دریافت فایل یا تأیید محتوای URL انجام نمی‌دهد. اگر آدرس سوره/آیه دارید، می‌توانید با `Ayah.getByKey('2:255')!.index` از `@ghoran/entity` اندیس مشترک بگیرید؛ پکیج صوت برای Gain به آن پکیج وابسته نیست.
95
+
96
+ برای lookup با شناسهٔ منبع فقط منابع مورد استفاده را ثبت کنید:
97
+
98
+ ```ts
99
+ import { createAudioNormalizer, parhizgar, ansarian } from '@ghoran/audio'
100
+
101
+ const audio = createAudioNormalizer({ sources: [parhizgar, ansarian] })
102
+ const gain = audio.getGain('parhizgar', 261)
103
+ const details = audio.getRecommendation('ansarian', 261)
104
+ ```
105
+
106
+ TypeScript شناسه‌ها را به منابع ثبت‌شده محدود می‌کند. منبع تکراری، هدف متفاوت یا snapshot ناسازگار پذیرفته نمی‌شود. lookup همگام است و هیچ I/O ندارد. ضرایب خطی پس از آماده‌سازی هر منبع cache می‌شوند؛ هیچ ضرب نمونه‌ای توسط این کتابخانه اجرا نمی‌شود.
107
+
108
+ ## سیاست‌های دیگر؛ فقط در صورت import
109
+
110
+ ورودی پیش‌فرض هر منبع، سیاست **‎−۲۰ LUFS** است. برای ‎−۲۳، ‎−۱۸ و ‎−۱۶، فقط همان منبع و سیاست را import کنید:
111
+
112
+ ```ts
113
+ import parhizgar from '@ghoran/audio/targets/-23/parhizgar'
114
+ import ansarian from '@ghoran/audio/targets/-23/ansarian'
115
+ ```
116
+
117
+ برای اپ با انتخاب پویا، loader اختیاری وجود دارد:
118
+
119
+ ```ts
120
+ import { loadAudioSource } from '@ghoran/audio/load'
121
+
122
+ const profile = await loadAudioSource('parhizgar', { targetLufs: -20 })
123
+ const gain = profile.getGain(0)
124
+ ```
125
+
126
+ مسیر `/load` در bundler می‌تواند chunkهای جداگانهٔ تمام گزینه‌های قابل انتخاب را **تولید** کند؛ فقط گزینهٔ درخواست‌شده را **بارگیری** می‌کند. برای حذف کامل سایر منابع از خروجی پروژه، ورودی‌های ثابت را به کار ببرید. فهرست منابع برای UI انتخاب قاری، جداست:
127
+
128
+ ```ts
129
+ import { audioSources } from '@ghoran/audio/catalog'
130
+ ```
131
+
132
+ ## حفاظت Peak و حفظ اصالت
133
+
134
+ سیاست فعلی Gain پایهٔ مجموعه را همراه با حفاظت True Peak اعمال می‌کند. اصلاح بخش ضبط و outlier استنباطی خودکار اعمال نمی‌شود. کل فایل یک Gain ثابت دارد؛ دامنهٔ طبیعی داخل آیه صاف نمی‌شود. هیچ MP3 تغییر یا دوباره Encode نشده است.
135
+
136
+ سقف True Peak برابر ‎−۱ dBTP و حاشیهٔ اضافی ۰٫۱۵ dB است. افزایش حداکثر ۸ و کاهش حداکثر ۱۸ dB است. Gain به گام‌های **۰٫۰۱ dB به سمت مقدار کمتر** تبدیل می‌شود؛ اختلاف از توصیهٔ دقیق کمتر از ۰٫۰۱ dB است و حفاظت Peak با عدد نهایی بررسی می‌شود. برای مثال Gain پایهٔ ‎−۷٫۵۳۳ به ‎−۷٫۵۴ تبدیل می‌شود. دقت ثابت، تعداد مقادیر و حجم داده را کاهش می‌دهد.
137
+
138
+ LUFS هدف، baseline مجموعه است؛ قرار نیست هر آیه به ‎−۲۰ برسد. اعداد بر قرارداد پخش مونو با کپی دامنهٔ یکسان به هر دو کانال تکیه دارند. در pan-law دیگر، توصیه‌ها نیاز به بازتولید دارند. جمع چند صوت هم‌زمان و تقویت دیگری پس از این Gain، به headroom جدا نیاز دارد.
139
+
140
+ ## تطبیق با نسخهٔ واقعی صوت
141
+
142
+ `getGain` یک lookup روی **صوت مرجع اندازه‌گیری‌شده** است؛ تغییر محتوای URL ثابت را تشخیص نمی‌دهد. `snapshotId` و `contentRevision` شناسهٔ نسخه‌اند و به‌تنهایی اثبات تطابق بایت‌های فایل نیستند. در `getRecommendation` مقدار `contentVerified` صریحاً `false` است.
143
+
144
+ برای مسیر سخت‌گیرانه، فقط manifest هش همان منبع را وارد کنید و SHA-256 واقعی فایل دریافت‌شده را بدهید:
145
+
146
+ ```ts
147
+ import parhizgar from '@ghoran/audio/sources/parhizgar'
148
+ import hashes from '@ghoran/audio/hashes/parhizgar'
149
+ import { getVerifiedAudioGain } from '@ghoran/audio/verify'
150
+
151
+ const gain = getVerifiedAudioGain(parhizgar, hashes, 261, actualAudioSha256)
152
+ // محتوای تغییرکرده، revision ناسازگار یا Gain ناموجود -> null
153
+ ```
154
+
155
+ هش از بایت‌های فایل اصلی است، نه PCM Decodeشده. محاسبهٔ هش را می‌توانید یک بار در مسیر دانلود/cache انجام دهید. کتابخانه صوت را دوباره دریافت نمی‌کند و WebCrypto/DOM/Node API در runtime لازم ندارد. manifest هش عمداً از دادهٔ Gain بزرگ‌تر و کاملاً اختیاری است. برای بارگیری پویا از `loadAudioContentManifest` در `/load` استفاده کنید.
156
+
157
+ ## منابع و وضعیت داده
158
+
159
+ شناسه‌ها: `parhizgar`, `ghamadi`, `husary`, `minshawy-murattal`, `minshawy-mujawwad`, `motaz`, `abdulbasit`, `almuiqly`, `jafarpour`, `ansarian`, `maleki`, `makarem-kabiri`, `fooladvand-hedayatfar`.
160
+
161
+ exportهای نام‌دار دوکلمه‌ای camelCase هستند: `minshawyMurattal`, `minshawyMujawwad`, `makaremKabiri`, `fooladvandHedayatfar`. subpath همیشه شناسهٔ اصلی خط‌تیره‌دار را دارد.
162
+
163
+ فهرست کامل ۸۱٬۰۶۸ مورد بررسی شده است؛ snapshot مرجع فعلی پس از پذیرش جایگزین‌ها برای همهٔ موارد Gain دارد. انتشار ۱۱ جایگزین در URL اصلی همچنان تأیید نشده است. موفقیت Decode، صحت محتوای آیه یا انتساب قاری را ثابت نمی‌کند. ۱۱۲ URL معیقلی برخلاف پسوند mp3 محتوای PCM دارند؛ انتخاب decoder باید از روی محتوای واقعی انجام شود.
164
+
165
+ ## توسعه و بازتولید
166
+
167
+ پکیج پخش، snapshot کم‌حجم و کنترل‌شدهٔ Gain پایه + استثناها را نگه می‌دارد. اندازه‌گیری‌های کامل و ابزار پژوهشی در [نسخهٔ آرشیوی](https://github.com/sabereen/ghoran/tree/fbd55d0fe9c3cf5559a0af9e0b6ca1e9da37d365/packages/audio) حفظ شده‌اند؛ گزارش‌های حجیم، نمودارها و تاریخچه‌های اجرایی داخل این پکیج نیستند.
168
+
169
+ ```sh
170
+ pnpm --filter @ghoran/audio build
171
+ pnpm --filter @ghoran/audio check:runtime
172
+ pnpm test
173
+ pnpm check:packages
174
+ ```
175
+
176
+ ماژول‌های مستقل هر منبع و سیاست در بیلد با Node تولید می‌شوند و خروجی تولیدشده در Git تکرار نمی‌شود. Python، FFmpeg و شبکه برای بیلد روزمره لازم نیستند. [RESEARCH.md](https://github.com/sabereen/ghoran/blob/main/packages/audio/RESEARCH.md) ورودی‌ها، مرجع ثابت و دستور بازتولید علمی را توضیح می‌دهد.
177
+
178
+ [دموی مقایسهٔ شنیداری](https://sabereen.github.io/ghoran/demo/audio/) امکان انتخاب هر ۹ قاری و ۴ ترجمه و مقایسهٔ همان صوت با Gain و بدون آن را دارد.
179
+
180
+ کد تحت MIT؛ ساختار سوره و آیه از [Tanzil Project](https://tanzil.net/docs/Quran_Metadata) است؛ منبع و روش اعتبارسنجی در آرشیو پژوهش حفظ شده‌اند. صوت‌های اصلی داخل پکیج npm توزیع نمی‌شوند.
@@ -0,0 +1,14 @@
1
+ //#region src/generated/metadata/abdulbasit.ts
2
+ const metadata = {
3
+ "id": "abdulbasit",
4
+ "nameFa": "عبدالباسط",
5
+ "kind": "recitation",
6
+ "urlTemplate": "https://asset.nasimrezvan.com/data/Abdulbasit/{file_stem}.mp3",
7
+ "baselinePlaybackLufs": -14.147,
8
+ "contentRevision": "1924d1d9671078fb7a5d3b90ad67c46a5b4e87bbd66798f5a5ade1dd4808bc19",
9
+ "measuredFiles": 6236,
10
+ "inventoryComplete": true,
11
+ "pendingPublicationFiles": 1
12
+ };
13
+ //#endregion
14
+ export { metadata as t };
@@ -0,0 +1,12 @@
1
+ import { r as createAudioSource } from "./playback-CeKsQsxV.mjs";
2
+ import { t as metadata } from "./abdulbasit-CgLk633T.mjs";
3
+ //#endregion
4
+ //#region src/sources/abdulbasit.ts
5
+ const abdulbasit = /* @__PURE__ */ createAudioSource(metadata, {
6
+ "targetLufs": -20,
7
+ "base": -586,
8
+ "overrides": [],
9
+ "unavailable": []
10
+ });
11
+ //#endregion
12
+ export { abdulbasit as t };
@@ -0,0 +1,12 @@
1
+ import { r as createAudioSource } from "./playback-CeKsQsxV.mjs";
2
+ import { t as metadata } from "./almuiqly-Ds8QVRUj.mjs";
3
+ //#endregion
4
+ //#region src/sources/almuiqly.ts
5
+ const almuiqly = /* @__PURE__ */ createAudioSource(metadata, {
6
+ "targetLufs": -20,
7
+ "base": -418,
8
+ "overrides": [],
9
+ "unavailable": []
10
+ });
11
+ //#endregion
12
+ export { almuiqly as t };
@@ -0,0 +1,14 @@
1
+ //#region src/generated/metadata/almuiqly.ts
2
+ const metadata = {
3
+ "id": "almuiqly",
4
+ "nameFa": "معیقلی",
5
+ "kind": "recitation",
6
+ "urlTemplate": "https://asset.nasimrezvan.com/data/AlMuiqly/{file_stem}.mp3",
7
+ "baselinePlaybackLufs": -15.825,
8
+ "contentRevision": "52c91d15c80762e8e003f9e1bfd4dbd51046240649d3ea1dea6332bfdd71a80b",
9
+ "measuredFiles": 6236,
10
+ "inventoryComplete": true,
11
+ "pendingPublicationFiles": 0
12
+ };
13
+ //#endregion
14
+ export { metadata as t };
@@ -0,0 +1,14 @@
1
+ //#region src/generated/metadata/ansarian.ts
2
+ const metadata = {
3
+ "id": "ansarian",
4
+ "nameFa": "انصاریان",
5
+ "kind": "translation",
6
+ "urlTemplate": "https://qmad.s3.ir-central1.arvanstorage.ir/translation/ansarian-iranseda/{file_stem}.mp3",
7
+ "baselinePlaybackLufs": -16.709700043360186,
8
+ "contentRevision": "68e07be1581e9ecb5781f1f2ba11e2796d3051588c4fa868b75401cf0d0179d8",
9
+ "measuredFiles": 6236,
10
+ "inventoryComplete": true,
11
+ "pendingPublicationFiles": 0
12
+ };
13
+ //#endregion
14
+ export { metadata as t };
@@ -0,0 +1,93 @@
1
+ import { r as createAudioSource } from "./playback-CeKsQsxV.mjs";
2
+ import { t as metadata } from "./ansarian-CsfxGgu4.mjs";
3
+ //#endregion
4
+ //#region src/sources/ansarian.ts
5
+ const ansarian = /* @__PURE__ */ createAudioSource(metadata, {
6
+ "targetLufs": -20,
7
+ "base": -330,
8
+ "overrides": [
9
+ [
10
+ 165,
11
+ -355,
12
+ true
13
+ ],
14
+ [
15
+ 172,
16
+ -335,
17
+ true
18
+ ],
19
+ [
20
+ 177,
21
+ -355,
22
+ true
23
+ ],
24
+ [
25
+ 199,
26
+ -345,
27
+ true
28
+ ],
29
+ [
30
+ 215,
31
+ -395,
32
+ true
33
+ ],
34
+ [
35
+ 237,
36
+ -375,
37
+ true
38
+ ],
39
+ [
40
+ 242,
41
+ -365,
42
+ true
43
+ ],
44
+ [
45
+ 392,
46
+ -375,
47
+ true
48
+ ],
49
+ [
50
+ 538,
51
+ -335,
52
+ true
53
+ ],
54
+ [
55
+ 548,
56
+ -335,
57
+ true
58
+ ],
59
+ [
60
+ 554,
61
+ -335,
62
+ true
63
+ ],
64
+ [
65
+ 578,
66
+ -335,
67
+ true
68
+ ],
69
+ [
70
+ 988,
71
+ -355,
72
+ true
73
+ ],
74
+ [
75
+ 993,
76
+ -345,
77
+ true
78
+ ],
79
+ [
80
+ 1276,
81
+ -345,
82
+ true
83
+ ],
84
+ [
85
+ 2605,
86
+ -355,
87
+ true
88
+ ]
89
+ ],
90
+ "unavailable": []
91
+ });
92
+ //#endregion
93
+ export { ansarian as t };
@@ -0,0 +1,7 @@
1
+ //#region src/ayah-index.ts
2
+ /** Shared address contract; deliberately contains no Quran addressing data. */
3
+ function assertAyahIndex(ayahIndex) {
4
+ if (!Number.isInteger(ayahIndex) || ayahIndex < 0 || ayahIndex >= 6236) throw new RangeError("Ayah index must be an integer from 0 to 6235");
5
+ }
6
+ //#endregion
7
+ export { assertAyahIndex as t };
@@ -0,0 +1,4 @@
1
+ import { o as AudioSource } from "./types-BiTocnkC.js";
2
+ //#region src/catalog.d.ts
3
+ export declare const audioSources: readonly AudioSource[];
4
+ //#endregion
@@ -0,0 +1,31 @@
1
+ import { t as metadata } from "./parhizgar-DI28CJpf.mjs";
2
+ import { t as metadata$1 } from "./ghamadi-Gq4oILyo.mjs";
3
+ import { t as metadata$2 } from "./husary-58J-Hbbz.mjs";
4
+ import { t as metadata$3 } from "./minshawy-murattal-DWTJ7Vbi.mjs";
5
+ import { t as metadata$4 } from "./minshawy-mujawwad-CF0_Aws9.mjs";
6
+ import { t as metadata$5 } from "./motaz-BPiSDPjo.mjs";
7
+ import { t as metadata$6 } from "./abdulbasit-CgLk633T.mjs";
8
+ import { t as metadata$7 } from "./almuiqly-Ds8QVRUj.mjs";
9
+ import { t as metadata$8 } from "./jafarpour-2Nco5LM6.mjs";
10
+ import { t as metadata$9 } from "./ansarian-CsfxGgu4.mjs";
11
+ import { t as metadata$10 } from "./maleki-BtTzBMIi.mjs";
12
+ import { t as metadata$11 } from "./makarem-kabiri-Di0qt0pO.mjs";
13
+ import { t as metadata$12 } from "./fooladvand-hedayatfar-DPOvoFnl.mjs";
14
+ //#region src/catalog.ts
15
+ const audioSources = /* @__PURE__ */ Object.freeze([
16
+ /* @__PURE__ */ Object.freeze(metadata),
17
+ /* @__PURE__ */ Object.freeze(metadata$1),
18
+ /* @__PURE__ */ Object.freeze(metadata$2),
19
+ /* @__PURE__ */ Object.freeze(metadata$3),
20
+ /* @__PURE__ */ Object.freeze(metadata$4),
21
+ /* @__PURE__ */ Object.freeze(metadata$5),
22
+ /* @__PURE__ */ Object.freeze(metadata$6),
23
+ /* @__PURE__ */ Object.freeze(metadata$7),
24
+ /* @__PURE__ */ Object.freeze(metadata$8),
25
+ /* @__PURE__ */ Object.freeze(metadata$9),
26
+ /* @__PURE__ */ Object.freeze(metadata$10),
27
+ /* @__PURE__ */ Object.freeze(metadata$11),
28
+ /* @__PURE__ */ Object.freeze(metadata$12)
29
+ ]);
30
+ //#endregion
31
+ export { audioSources };
@@ -0,0 +1,12 @@
1
+ import { r as createAudioSource } from "./playback-CeKsQsxV.mjs";
2
+ import { t as metadata } from "./fooladvand-hedayatfar-DPOvoFnl.mjs";
3
+ //#endregion
4
+ //#region src/sources/fooladvand-hedayatfar.ts
5
+ const fooladvandHedayatfar = /* @__PURE__ */ createAudioSource(metadata, {
6
+ "targetLufs": -20,
7
+ "base": -548,
8
+ "overrides": [],
9
+ "unavailable": []
10
+ });
11
+ //#endregion
12
+ export { fooladvandHedayatfar as t };
@@ -0,0 +1,14 @@
1
+ //#region src/generated/metadata/fooladvand-hedayatfar.ts
2
+ const metadata = {
3
+ "id": "fooladvand-hedayatfar",
4
+ "nameFa": "فولادوند",
5
+ "kind": "translation",
6
+ "urlTemplate": "https://asset.nasimrezvan.com/data/Fooladvand_Hedayatfar/{file_stem}.mp3",
7
+ "baselinePlaybackLufs": -14.528,
8
+ "contentRevision": "46f5911b18a2b85829e1ebb8b686e229e3c6c2abaa46ed369c53dba1d9912e56",
9
+ "measuredFiles": 6236,
10
+ "inventoryComplete": true,
11
+ "pendingPublicationFiles": 0
12
+ };
13
+ //#endregion
14
+ export { metadata as t };
@@ -0,0 +1,20 @@
1
+ import { r as createAudioSource } from "./playback-CeKsQsxV.mjs";
2
+ import { t as metadata } from "./ghamadi-Gq4oILyo.mjs";
3
+ //#endregion
4
+ //#region src/sources/ghamadi.ts
5
+ const ghamadi = /* @__PURE__ */ createAudioSource(metadata, {
6
+ "targetLufs": -20,
7
+ "base": -421,
8
+ "overrides": [[
9
+ 235,
10
+ -1275,
11
+ true
12
+ ], [
13
+ 3314,
14
+ -835,
15
+ true
16
+ ]],
17
+ "unavailable": []
18
+ });
19
+ //#endregion
20
+ export { ghamadi as t };