Spaces:
Running on Zero
Running on Zero
| """Song/Lyrics emotional journey data and sequence generation. | |
| This module provides: | |
| - EMOTIONAL_STATES: Dictionary of emotional states for song-based narratives | |
| - generate_song_sequence: Function to generate emotional journey sequences | |
| """ | |
| import json | |
| import random | |
| # Emotional states organized by mood category | |
| EMOTIONAL_STATES = { | |
| "joy": [ | |
| ("Euphoria", "Pure, overwhelming happiness radiates through every moment", ["celebration", "peak"]), | |
| ("Contentment", "A gentle satisfaction with the present moment", ["peace", "gratitude"]), | |
| ("Excitement", "Anticipation of wonderful things bubbles up inside", ["energy", "possibility"]), | |
| ("Love's Bloom", "The warmth of affection fills every corner of being", ["romance", "connection"]), | |
| ("Triumph", "Victory brings a surge of proud accomplishment", ["achievement", "power"]), | |
| ], | |
| "sorrow": [ | |
| ("Heartbreak", "The ache of loss echoes through an empty chest", ["pain", "separation"]), | |
| ("Melancholy", "A bittersweet sadness colors everything in blue", ["reflection", "beauty"]), | |
| ("Grief", "The weight of absence presses down relentlessly", ["mourning", "memory"]), | |
| ("Longing", "An unreachable desire stretches toward the horizon", ["yearning", "distance"]), | |
| ("Regret", "If only things had been different...", ["hindsight", "weight"]), | |
| ], | |
| "anger": [ | |
| ("Rage", "White-hot fury demands expression and release", ["intensity", "destruction"]), | |
| ("Frustration", "Barriers block every attempt at progress", ["struggle", "tension"]), | |
| ("Betrayal", "Trust shattered leaves sharp edges everywhere", ["wound", "disbelief"]), | |
| ("Defiance", "A refusal to accept what others demand", ["rebellion", "strength"]), | |
| ("Righteous Fire", "Injustice ignites a burning need for action", ["purpose", "conviction"]), | |
| ], | |
| "fear": [ | |
| ("Dread", "Something terrible approaches with inevitable footsteps", ["anticipation", "darkness"]), | |
| ("Anxiety", "Uncertainty spirals into cascading worries", ["overwhelm", "paralysis"]), | |
| ("Vulnerability", "Exposed and unprotected in a hostile world", ["fragility", "need"]), | |
| ("Paranoia", "Every shadow hides a threat, every silence a danger", ["suspicion", "isolation"]), | |
| ("Terror", "Primal fear strips away everything but survival", ["crisis", "instinct"]), | |
| ], | |
| "hope": [ | |
| ("Dawn Breaking", "After darkness, the first light of possibility appears", ["renewal", "promise"]), | |
| ("Second Chance", "An opportunity to make things right emerges", ["redemption", "gratitude"]), | |
| ("Dreams Forming", "Visions of what could be take shape in the mind", ["imagination", "aspiration"]), | |
| ("Faith Restored", "Belief in something greater returns", ["trust", "meaning"]), | |
| ("Courage Rising", "Fear transforms into determination to face what comes", ["strength", "resolve"]), | |
| ], | |
| "nostalgia": [ | |
| ("Golden Memories", "The past glows with a warm, amber light", ["comfort", "loss"]), | |
| ("Innocence Lost", "Remembering before the world became complicated", ["youth", "purity"]), | |
| ("Phantom Touch", "The sensation of someone no longer present", ["love", "absence"]), | |
| ("Places Remembered", "Spaces that hold pieces of who you were", ["identity", "change"]), | |
| ("Old Songs", "Melodies that transport you across time", ["emotion", "connection"]), | |
| ], | |
| "peace": [ | |
| ("Stillness", "The noise fades and silence becomes sanctuary", ["calm", "presence"]), | |
| ("Acceptance", "What is, simply is - no struggle remains", ["surrender", "wisdom"]), | |
| ("Unity", "Separation dissolves into connection with all things", ["transcendence", "belonging"]), | |
| ("Forgiveness", "The weight of grudges lifts away", ["release", "healing"]), | |
| ("Home", "A sense of belonging settles into the bones", ["safety", "arrival"]), | |
| ], | |
| } | |
| # Song structure elements | |
| SONG_STRUCTURES = { | |
| "verse": "The story unfolds, details emerge", | |
| "chorus": "The central truth repeats, driving home the message", | |
| "bridge": "A shift in perspective, a new angle on the theme", | |
| "outro": "The emotion settles, leaving its lasting impression", | |
| } | |
| def generate_song_sequence(verse_count, include_joy, include_sorrow, include_anger, | |
| include_fear, include_hope, include_nostalgia, include_peace, | |
| emotional_arc="journey"): | |
| """Generate an emotional journey sequence based on song structure. | |
| Args: | |
| verse_count: Number of emotional beats (3-10) | |
| include_*: Include specific emotional categories | |
| emotional_arc: 'journey' (varied), 'crescendo' (building), 'resolution' (tension to peace) | |
| Returns: | |
| Tuple of (list_output, json_output, prompts_output) | |
| """ | |
| available = [] | |
| if include_joy: | |
| available.extend([(e[0], e[1], "joy", e[2]) for e in EMOTIONAL_STATES["joy"]]) | |
| if include_sorrow: | |
| available.extend([(e[0], e[1], "sorrow", e[2]) for e in EMOTIONAL_STATES["sorrow"]]) | |
| if include_anger: | |
| available.extend([(e[0], e[1], "anger", e[2]) for e in EMOTIONAL_STATES["anger"]]) | |
| if include_fear: | |
| available.extend([(e[0], e[1], "fear", e[2]) for e in EMOTIONAL_STATES["fear"]]) | |
| if include_hope: | |
| available.extend([(e[0], e[1], "hope", e[2]) for e in EMOTIONAL_STATES["hope"]]) | |
| if include_nostalgia: | |
| available.extend([(e[0], e[1], "nostalgia", e[2]) for e in EMOTIONAL_STATES["nostalgia"]]) | |
| if include_peace: | |
| available.extend([(e[0], e[1], "peace", e[2]) for e in EMOTIONAL_STATES["peace"]]) | |
| if not available: | |
| return "Select at least one emotional category!", "{}", "" | |
| sequence = [] | |
| random.shuffle(available) | |
| # Apply emotional arc logic | |
| if emotional_arc == "crescendo": | |
| # Build from calm to intense | |
| intensity_order = ["peace", "nostalgia", "hope", "joy", "fear", "sorrow", "anger"] | |
| available.sort(key=lambda x: intensity_order.index(x[2]) if x[2] in intensity_order else 3) | |
| elif emotional_arc == "resolution": | |
| # Start intense, end peaceful | |
| intense = [e for e in available if e[2] in ["anger", "fear", "sorrow"]] | |
| calm = [e for e in available if e[2] in ["peace", "hope", "joy"]] | |
| random.shuffle(intense) | |
| random.shuffle(calm) | |
| available = intense + calm | |
| sequence = available[:verse_count] | |
| if not sequence: | |
| return "No emotional states available!", "{}", "" | |
| # Assign song structure elements | |
| structure_labels = [] | |
| for i in range(len(sequence)): | |
| if i == 0: | |
| structure_labels.append("INTRO") | |
| elif i == len(sequence) - 1: | |
| structure_labels.append("OUTRO") | |
| elif i == len(sequence) // 2: | |
| structure_labels.append("BRIDGE") | |
| elif i % 2 == 0: | |
| structure_labels.append("CHORUS") | |
| else: | |
| structure_labels.append("VERSE") | |
| # Format as list | |
| list_output = f"## Emotional Journey ({emotional_arc.title()} Arc)\n\n" | |
| for i, ((name, desc, mood, themes), structure) in enumerate(zip(sequence, structure_labels), 1): | |
| themes_str = ", ".join(themes) | |
| list_output += f"**{i}. [{structure}] {name}** ({mood})\n{desc}\n*Themes: {themes_str}*\n\n" | |
| # Format as config JSON | |
| config = {"emotional_journey": {}} | |
| for i, ((name, desc, mood, themes), structure) in enumerate(zip(sequence, structure_labels), 1): | |
| state_name = name.lower().replace(" ", "_").replace("'", "").replace("-", "_") | |
| current_state_id = f"moment_{i}_{state_name}" | |
| themes_str = ", ".join(themes) | |
| # Determine next state | |
| if i < len(sequence): | |
| next_name = sequence[i][0] | |
| next_state_name = next_name.lower().replace(" ", "_").replace("'", "").replace("-", "_") | |
| next_state_id = f"moment_{i+1}_{next_state_name}" | |
| else: | |
| next_state_id = "journey_end" | |
| config["emotional_journey"][current_state_id] = { | |
| "description": f"[{structure}] {desc}\n\n*Feeling: {mood} | {themes_str}*", | |
| "media_prompt": f"Abstract emotional art: {name} - {mood} mood, {desc}, visual representation of {themes_str}", | |
| "choices": ["Feel the Next Wave"], | |
| "transitions": { | |
| "Feel the Next Wave": next_state_id | |
| } | |
| } | |
| # Add ending state | |
| first_moment = sequence[0][0].lower().replace(" ", "_").replace("'", "").replace("-", "_") | |
| config["emotional_journey"]["journey_end"] = { | |
| "description": "The emotional journey comes full circle. Every feeling has been felt, every moment lived.", | |
| "choices": ["Experience Again"], | |
| "transitions": { | |
| "Experience Again": f"moment_1_{first_moment}" | |
| } | |
| } | |
| json_output = json.dumps(config, indent=2) | |
| # Format prompts | |
| prompts_output = f"## Emotional Art Prompts ({emotional_arc.title()})\n\n" | |
| for i, (name, desc, mood, themes) in enumerate(sequence, 1): | |
| themes_str = ", ".join(themes) | |
| prompts_output += f"Abstract emotional art: {name} - {mood}, {themes_str}\n" | |
| return list_output, json_output, prompts_output | |
| if __name__ == "__main__": | |
| list_out, json_out, prompts_out = generate_song_sequence( | |
| 6, True, True, False, False, True, True, True, "resolution" | |
| ) | |
| print(list_out) | |