Sequencers
Algorithmic composition tools including raga generators, cellular automata, and non-linear sequencing.
Raga Generator
Indian Raga Sequencer
sequencer.raga_generatorTime-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.GOLMap cellular automaton evolution to musical sequences with EDO tuning support.
Available Modules
Standard Game of Life mapped to 12-TET chromatic scale. Grid rows = pitches, columns = time steps.
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_sequencerConvert text input into musical sequences with sample clustering support.
Available Modules
Convert text strings to note sequences based on character mapping.
Use audio sample clusters to generate varied sequences.
Play back samples from defined clusters.
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_linearGenerate 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_choiceProbabilistic 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)