Raga Generator

Indian Raga Sequencer

sequencer.raga_generator

Time-of-day based raga selection with fractal rhythm generation and probabilistic note selection.

choose_raga()

Selects an appropriate raga based on the current time of day, following traditional Indian musical practice.

Returns: Dictionary with raga name, intervals, and mood information.

generate_fractal_rhythm()
Parameter Type Default Description
core_pattern list required Base binary pattern [0, 1, ...]
depth int 3 Fractal recursion depth
randomness float 0.2 Probability of pattern flip (0-1)

Returns: Expanded binary rhythm pattern

select_next_note()
Parameter Type Description
current_note int Current scale degree (0-7)
intervals list Raga interval list

Returns: Next note based on probability weights

generate_random_core_pattern()
Parameter Type Default Description
length int 6 Pattern length

Returns: Random binary pattern [0, 1, 0, 1, ...]

Ragas by Time of Day

Time Period Hours Ragas
Early Morning 4 AM - 7 AM Bhairav, Ramkali
Late Morning 7 AM - 10 AM Bilawal, Jaunpuri
Afternoon 10 AM - 2 PM Sarang, Brindavani Sarang
Evening 5 PM - 10 PM Yaman, Kafi
Night 10 PM - 4 AM Malkauns, Bageshree

Example Usage

from audio_dsp.sequencer.raga_generator import (
    choose_raga,
    generate_fractal_rhythm,
    generate_random_core_pattern,
    select_next_note
)
from audio_dsp.synth import SubtractiveSynth
import numpy as np
import soundfile as sf

# Get raga appropriate for current time
raga = choose_raga()
print(f"Selected: {raga['name']}")

# Generate fractal rhythm pattern
core = generate_random_core_pattern(length=5)
rhythm = generate_fractal_rhythm(core, depth=4, randomness=0.15)
print(f"Pattern: {rhythm}")

# Generate melody using probabilistic note selection
synth = SubtractiveSynth()
synth.osc_wave = "sine"
synth.attack = 0.1
synth.release = 0.3

base_freq = 220  # A3
current_note = 0
melody_audio = []

for beat in rhythm:
    if beat == 1:
        # Play a note
        freq = base_freq * (2 ** (raga['intervals'][current_note] / 12))
        note = synth.synthesize(freq, 0.25)
        current_note = select_next_note(current_note, raga['intervals'])
    else:
        # Rest
        note = np.zeros(int(0.25 * 44100))

    melody_audio.append(note)

sf.write("raga_melody.wav", np.concatenate(melody_audio), 44100)

Game of Life Sequencer

Conway's Game of Life

sequencer.GOL

Map cellular automaton evolution to musical sequences with EDO tuning support.

Available Modules

sequencer.GOL.game_of_life

Standard Game of Life mapped to 12-TET chromatic scale. Grid rows = pitches, columns = time steps.

sequencer.GOL.game_of_life_edo

EDO (Equal Division of Octave) variant supporting microtonal scales (19-EDO, 31-EDO, etc.).

Concept

The Game of Life sequencer maps a 2D cellular automaton grid to musical events:

  • Rows = Pitch (higher row = higher pitch)
  • Columns = Time (left to right)
  • Live cells = Notes played
  • Dead cells = Silence

Example Usage

from audio_dsp.sequencer.GOL.game_of_life import GameOfLifeSequencer

# Create sequencer with 8 pitches, 16 time steps
gol = GameOfLifeSequencer(rows=8, cols=16)

# Initialize with random pattern
gol.randomize(density=0.3)

# Generate sequence for 4 generations
sequence = gol.generate(generations=4, base_freq=220)

# Export to audio
gol.export("gol_sequence.wav", bpm=120)

# EDO variant for microtonal
from audio_dsp.sequencer.GOL.game_of_life_edo import GameOfLifeEDO

gol_micro = GameOfLifeEDO(rows=19, cols=16, divisions=19)
gol_micro.randomize()
gol_micro.generate(generations=3)

Text-Based Sequencer

Text to Music

sequencer.text_sequencer

Convert text input into musical sequences with sample clustering support.

Available Modules

text_sequencer.py

Convert text strings to note sequences based on character mapping.

cluster_sequencer.py

Use audio sample clusters to generate varied sequences.

cluster_sampler.py

Play back samples from defined clusters.

sample_clustering.py

K-means clustering of audio samples by spectral features.

Example Usage

from audio_dsp.sequencer.text_sequencer.text_sequencer import TextSequencer

# Create text-to-music converter
seq = TextSequencer()

# Convert text to note sequence
notes = seq.text_to_notes("Hello World!")
print(notes)  # List of frequencies/MIDI notes

# Generate audio from text
seq.generate_audio(
    text="The quick brown fox",
    output_file="text_music.wav",
    duration_per_char=0.2
)

# Sample clustering
from audio_dsp.sequencer.text_sequencer.sample_clustering import cluster_samples

# Cluster drum samples by spectral similarity
clusters = cluster_samples(
    sample_dir="drums/",
    n_clusters=4
)

Non-Linear Sequencer

Chaotic Sequencing

sequencer.non_linear

Generate sequences using strange attractors and chaotic systems.

Concept

Non-linear sequencing uses mathematical chaos (Lorenz attractor, logistic map, etc.) to generate unpredictable but structured musical patterns. The chaotic systems produce values that are deterministic but highly sensitive to initial conditions, creating organic-feeling sequences.

Example Usage

from audio_dsp.sequencer.non_linear.non_linear_seq import NonLinearSequencer

# Create chaotic sequencer
seq = NonLinearSequencer()

# Generate using Lorenz attractor
sequence = seq.lorenz_sequence(
    steps=64,
    sigma=10.0,
    rho=28.0,
    beta=8.0/3.0
)

# Map to musical scale
notes = seq.map_to_scale(sequence, scale="minor", root=60)

# Logistic map for rhythm
rhythm = seq.logistic_map(
    steps=32,
    r=3.9,  # Chaos parameter (3.57-4.0 for chaos)
    x0=0.5  # Initial value
)

Melody Choice

Algorithmic Melody

sequencer.melody_choice

Probabilistic and rule-based melody generation algorithms.

Example Usage

from audio_dsp.sequencer.melody_choice import MelodyGenerator

gen = MelodyGenerator()

# Generate melody with constraints
melody = gen.generate(
    length=16,
    scale="pentatonic",
    root=60,  # Middle C
    range_octaves=2,
    step_preference=0.7,  # Prefer stepwise motion
    contour="arch"  # Overall shape
)

# Apply rhythmic pattern
rhythm = [1, 0.5, 0.5, 1, 1, 0.5, 0.5, 2]
sequence = gen.apply_rhythm(melody, rhythm)