Ragas¶
Hindustani ragas — the living melodic forms of North Indian classical music.
A thaat is a parent scale; a raga is what musicians actually play. A raga is more than its notes: it has an ascending line (aroha) and a descending line (avaroha) that often differ, a characteristic catch- phrase (pakad) that identifies it in a few notes, a most-important note (vadi) and its second (samvadi), a time of day or season it belongs to, and an emotional flavour (rasa).
This module encodes a representative set of the best-known ragas. Swaras are written in the usual ASCII sargam:
S Sa (tonic) r/R komal / shuddha Re g/G komal / shuddha Ga m/M shuddha / tivra Ma P Pa d/D komal / shuddha Dha n/N komal / shuddha Ni
A trailing ' raises a swara an octave, a trailing . lowers it.
Lowercase is komal (flattened), uppercase is shuddha (natural), and M
is tivra (sharpened) Ma.
Ragas vary by gharana and region; these are common, widely-taught forms.
Example:
>>> from pytheory import Raga
>>> yaman = Raga.get("yaman")
>>> yaman.aroha_swaras()
['N.', 'R', 'G', 'M', 'D', 'N', "S'"]
>>> [t.name for t in yaman.scale_tones("C")]
['C', 'D', 'E', 'F#', 'G', 'A', 'B']
>>> yaman.time, yaman.rasa
('evening', 'serene, romantic')
- class pytheory.ragas.Raga(name, *, thaat, aroha, avaroha, vadi, samvadi, time, rasa, pakad=None, aka=None, tradition='hindustani')[source]¶
Bases:
objectA Hindustani raga: its melodic rules, mood, and time.
- name¶
the raga’s name.
- thaat¶
parent scale (one of the ten thaats).
- aroha¶
ascending line (sargam string).
- avaroha¶
descending line (sargam string).
- pakad¶
characteristic identifying phrase (sargam string).
- vadi¶
the most important (sonant) swara.
- samvadi¶
the second-most important (consonant) swara.
- time¶
the time of day (or season) the raga belongs to.
- rasa¶
its emotional flavour.
- aka¶
alternative names.
- __init__(name, *, thaat, aroha, avaroha, vadi, samvadi, time, rasa, pakad=None, aka=None, tradition='hindustani')[source]¶
- just_ratios() dict[source]¶
Each distinct swara’s just-intonation ratio from Sa.
These are the shruti intervals — 5-limit ratios like 5/4 for Ga and 45/32 for tivra Ma — that the raga is meant to be intoned in, rather than the tempered 12-TET grid.
Example:
>>> Raga.get("yaman").just_ratios()["G"] Fraction(5, 4)
- just_frequencies(sa='C4') list[float][source]¶
The aroha→avaroha run as just-intoned frequencies (Hz).
Sa is movable: it’s pinned to sa and the shruti ratios are built on top, so you get authentic intonation in any key.
- shruti_table(sa='C') list[dict][source]¶
Per-swara intonation detail: ratio, Hz, and cents off 12-TET.
Shows how far each shruti sits from the tempered piano — e.g. the just major 3rd (Ga, 5/4) is ~14 cents flatter than the equal-tempered E.
- render(sa='C4', *, synth='sitar', t=420, envelope='pluck', just=True, reverb=0.35)[source]¶
Render the aroha→avaroha run to a mono sample buffer.
Notes are laid end to end and a hall reverb is mixed over the whole phrase, so the tail of one swara bleeds into the next — much closer to how a raga actually breathes than dry, separate notes. Returns a NumPy array (no audio device needed).
- Parameters:
sa – the tonic for Sa.
synth – waveform name (default sitar).
t – duration per swara in ms.
envelope – ADSR preset name.
just – just intonation (True, default) vs tempered 12-TET.
reverb – wet mix 0..1 (0 disables); default 0.35.
- play(sa='C4', *, synth='sitar', t=420, envelope='pluck', just=True, reverb=0.35)[source]¶
Play the aroha then avaroha through the speakers.
Defaults to the sitar voice in just intonation (the shruti tuning a raga is meant to be heard in), with a touch of reverb so the phrase rings like a hall. Pass
just=Falsefor tempered 12-TET,reverb=0for a dry run, or any synth name you like.
- classmethod get(name: str) Raga[source]¶
Look up a raga by name (case-insensitive, ignores spaces).
An exact name match always wins over an alias, so a real raga is never shadowed by another’s alternative spelling.
- classmethod by_time(period: str) list[Raga][source]¶
Ragas whose time of day matches (substring, case-insensitive).